Transposh WordPress Translation - Version 0.0.3

Version Description

Download this release

Release Info

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

Code changes from version 0.0.2 to 0.0.3

Files changed (5) hide show
  1. js/transposh.js +12 -2
  2. parser.php +639 -502
  3. readme.txt +6 -3
  4. transposh.php +119 -90
  5. transposh_widget.php +7 -8
js/transposh.js CHANGED
@@ -44,7 +44,17 @@ function hint(original)
44
  TEXTFONTCLASS,'oltxtD',
45
  AUTOSTATUS,WRAP);
46
  }
47
-
 
 
 
 
 
 
 
 
 
 
48
  //Open translation dialog
49
  function translate_dialog(original, trans, lang, post_url, segment_id)
50
  {
@@ -59,7 +69,7 @@ var dialog = ''+
59
  '<input type="hidden" id="tr_original" name="original" value="' + escape(original) +'">' +
60
  '<input type="hidden" id="tr_lang" name="lang" value="'+lang+'">' +
61
  '<input type="hidden" name="translation_posted" value= "1">' +
62
- '<p><input type="submit" value="Translate"><\/p>' +
63
  ('<\/div><\/form>');
64
 
65
  display_dialog(caption, dialog);
44
  TEXTFONTCLASS,'oltxtD',
45
  AUTOSTATUS,WRAP);
46
  }
47
+
48
+ // fetch translation from google translate...
49
+ function getgt(lang)
50
+ {
51
+ google.language.translate($("#tr_original_unescaped").text(), "", lang, function(result) {
52
+ if (!result.error) {
53
+ $("#tr_translation").attr('value',result.translation);
54
+ }
55
+ });
56
+ }
57
+
58
  //Open translation dialog
59
  function translate_dialog(original, trans, lang, post_url, segment_id)
60
  {
69
  '<input type="hidden" id="tr_original" name="original" value="' + escape(original) +'">' +
70
  '<input type="hidden" id="tr_lang" name="lang" value="'+lang+'">' +
71
  '<input type="hidden" name="translation_posted" value= "1">' +
72
+ '<p><input onclick="getgt(\''+lang+'\')" type="button" value="Get Suggestion!"/>&nbsp;<input type="submit" value="Translate"/><\/p>' +
73
  ('<\/div><\/form>');
74
 
75
  display_dialog(caption, dialog);
parser.php CHANGED
@@ -20,31 +20,31 @@
20
  * Contains the core functionality of the html parser. I.e. break into translation segments,
21
  * fetch translation and update the translated page.
22
  * This file should include only general purpose parser functionality while using callbacks
23
- * to obtain WorkdPress specific capabilities, e.g. db access.
24
  */
25
 
26
 
27
  require_once("constants.php");
28
 
29
- //The language to which the current page will be translated to.
30
  $lang;
31
-
32
  //The html page which starts contains the content being translated
33
  $page;
34
-
35
  //Marks the current position of the translation process within the page
36
  $pos = 0;
37
 
38
  //Contains the stack of tag in the current position within the page
39
  $tags_list = array();
40
 
41
- //The translated html page
42
  $tr_page;
43
-
44
- //Points to the last character that have been copied from the original to the translated page.
45
  $tr_mark = 0;
46
 
47
- //Is the current use is in edit mode.
48
  $is_edit_mode = FALSE;
49
 
50
  //Segment identifier within tags (span/img) mainly for use by js code on the client
@@ -53,128 +53,134 @@ $segment_id = 0;
53
  //Is current position within the body tag
54
  $is_in_body = FALSE;
55
 
 
 
 
56
  /*
57
  * Parse the html page into tags, identify translateable string which
58
- * will be translated.
59
  */
60
  function process_html()
61
  {
62
-
63
-
64
- global $page, $tr_page, $pos, $tags_list, $lang;
65
- $no_translate = 0;
66
- $page_length = strlen($page);
67
-
68
- while($pos < $page_length)
69
- {
70
- //find beginning of next tag
71
- $pos = strpos($page, '<', $pos);
72
- if($pos === FALSE)
73
- {
74
- //
75
- break;
76
- }
77
- $pos++;
78
-
79
- //Get the element identifying this tag
80
- $element = get_element();
81
-
82
- if(should_skip_element($element))
83
- {
84
- //do nothing
85
- }
86
- else
87
- {
88
- //Mark tag start position
89
- $tag_start = $pos;
90
-
91
- //skip to the '>' marking the end of the element
92
- $pos = strpos($page, '>', $pos);
93
-
94
- //Mark tag end position
95
- $tag_end = $pos;
96
-
97
- if($page[$pos-1] == '/')
98
- {
99
- //single line tag - no need to update tags list
100
- process_tag_init($element, $tag_start, $tag_end);
101
- }
102
- else if($element[0] != '/')
103
- {
104
- if(!$no_translate)
105
- {
106
- process_tag_init($element, $tag_start, $tag_end);
107
- }
108
-
109
- $tags_list[] = $element;
110
-
111
- //Look for the no translate class
112
- if(stripos($element, NO_TRANSLATE_CLASS) !== FALSE)
113
- {
114
- $no_translate++;
115
- }
116
- }
117
- else
118
- {
119
- $popped_element = array_pop($tags_list);
120
- if(!$no_translate)
121
- {
122
- process_tag_termination($element);
123
- }
124
-
125
- //Look for the no translate class
126
- if(stripos($popped_element, NO_TRANSLATE_CLASS) !== FALSE)
127
- {
128
- $no_translate--;
129
- }
130
- }
131
-
132
- $pos++;
133
-
134
- //skip processing while enclosed within a tag marked by no_translate
135
- if(!$no_translate)
136
- {
137
- process_current_tag();
138
- }
139
-
140
- }
141
- }
142
-
143
- if(strlen($tr_page) > 0)
144
- {
145
- //Some translation has been taken place. Complete the translated
146
- //page up to the full contents of the original page.
147
- update_translated_page(strlen($page), -1, "");
148
- }
149
-
150
-
 
 
 
151
  }
152
 
153
 
154
  /*
155
  * Determine if the specified element should be skipped. If so the position
156
  * is moved past end of tag.
157
- * Return TRUE if element is skipped otherwise FALSE.
158
  */
159
  function should_skip_element(&$element)
160
  {
161
- global $page, $pos;
162
- $rc = TRUE;
163
-
164
- if(strncmp($element, "!DOCTYPE", 8) == 0)
165
- {
166
- $pos = strpos($page, '>', $pos);
167
- }
168
- else if(strncmp($element, "!--", 3) == 0)
169
- {
170
- $pos = strpos($page, '-->', $pos);
171
- }
172
- else
173
- {
174
- $rc = FALSE;
175
- }
176
-
177
- return $rc;
178
  }
179
 
180
  /*
@@ -183,26 +189,28 @@ function should_skip_element(&$element)
183
  */
184
  function process_tag_init(&$element, $start, $end)
185
  {
186
- switch ($element)
187
- {
188
- case 'a':
189
- process_anchor_tag($start, $end);
190
- break;
191
- case 'div' :
192
- case 'span':
193
- process_span_or_div_tag($element, $start, $end);
194
- break;
195
- case 'html':
196
- process_html_tag($start, $end);
197
- break;
198
- case 'body':
199
- global $is_in_body;
200
- $is_in_body = TRUE;
201
- break;
202
-
203
-
204
- }
205
-
 
 
206
  }
207
 
208
 
@@ -213,55 +221,55 @@ function process_tag_init(&$element, $start, $end)
213
  */
214
  function process_span_or_div_tag(&$element, $start, $end)
215
  {
216
-
217
- $cls = get_attribute($start, $end, 'class');
218
-
219
- if($cls == NULL)
220
- {
221
- return;
222
- }
223
-
224
- //Look for the no translate class
225
- if(stripos($cls, NO_TRANSLATE_CLASS) === FALSE)
226
- {
227
- return;
228
- }
229
-
230
- //Mark the element as not translatable
231
- $element .= "." . NO_TRANSLATE_CLASS;
232
  }
233
 
234
 
235
  /*
236
- * Process html tag. Set the direction for rtl languages.
237
  *
238
  */
239
  function process_html_tag($start, $end)
240
  {
241
- global $lang, $rtl_languages;
242
-
243
- if(!(in_array ($lang, $rtl_languages)))
244
- {
245
- return;
246
- }
247
-
248
- $dir = get_attribute($start, $end, 'dir');
249
-
250
- if($dir == NULL)
251
- {
252
-
253
- //attribute does not exist - add it
254
- update_translated_page($end, -1, 'dir="rtl"');
255
- }
256
- else
257
- {
258
- $dir = 'rtl';
259
-
260
- //rewrite url in translated page
261
- update_translated_page($start, $end, $dir);
262
-
263
- }
264
-
265
  }
266
 
267
 
@@ -271,33 +279,40 @@ function process_html_tag($start, $end)
271
  */
272
  function process_tag_termination(&$element)
273
  {
274
- global $pos, $tags_list, $page;
275
-
276
-
277
  }
278
 
279
 
280
  /*
281
- * Return the element id within the current tag.
282
  */
283
  function get_element()
284
  {
285
-
286
- global $page, $pos;
287
-
288
- skip_white_space();
289
-
290
- $start = $pos;
291
-
292
- //keep scanning till the first white space or the '>' mark
293
- while($pos < strlen($page) && $page[$pos] != ' '&&
294
- $page[$pos] != '>' && $page[$pos] != '\t')
295
- {
296
- $pos++;
297
- }
298
-
299
-
300
- return substr($page,$start, $pos - $start);
 
 
 
 
 
 
 
301
  }
302
 
303
  /*
@@ -305,60 +320,60 @@ function get_element()
305
  * end position within the buffer.
306
  * Returns the string containing the attribute if available otherwise NULL.
307
  * In addition the start and end position are moved to boundaries of the
308
- * attribute's value.
309
  */
310
  function get_attribute(&$start, &$end, $id)
311
  {
312
- global $page;
313
-
314
- //look for the id within the given limits.
315
- while($start < $end)
316
- {
317
- $index = 0;
318
-
319
- while($start < $end && $page[$start + $index] == $id[$index]
320
- && $index < strlen($id))
321
- {
322
- $index++;
323
- }
324
-
325
- if($index == strlen($id))
326
- {
327
- //we have match
328
- break;
329
- }
330
-
331
- $start++;
332
- }
333
-
334
- if($start == $end)
335
- {
336
- return NULL;
337
- }
338
-
339
- //look for the " or ' marking start of attribute's value
340
- while($start < $end && $page[$start] != '"' && $page[$start] != "'")
341
- {
342
- $start++;
343
- }
344
-
345
- $start++;
346
- if($start >= $end)
347
- {
348
- return NULL;
349
- }
350
-
351
- $tmp = $start + 1;
352
- //look for the " or ' marking the end of attribute's value
353
- while($tmp < $end && $page[$tmp] != '"' && $page[$tmp] != "'")
354
- {
355
- $tmp++;
356
- }
357
-
358
- $end = $tmp - 1;
359
-
360
-
361
- return substr($page, $start, $end - $start + 1);
362
  }
363
 
364
  /*
@@ -368,48 +383,120 @@ function get_attribute(&$start, &$end, $id)
368
  */
369
  function process_current_tag()
370
  {
371
- global $page, $pos, $tags_list, $is_in_body;
372
-
373
- $current_tag = end($tags_list);
374
-
375
-
376
-
377
- //translate only elements within the body or title
378
- if($is_in_body || $current_tag == 'title')
379
- {
380
- skip_white_space();
381
- $start = $pos;
382
- $page_length = strlen($page);
383
-
384
- while($pos < $page_length && $page[$pos] != '<')
385
- {
386
- //will break translation unit when one of the following characters is reached: .,
387
- if(is_sentence_breaker($pos))
388
- {
389
- translate_text($start);
390
- $pos++;
391
- $start = $pos;
392
- }
393
- else if(($end_of_entity = is_html_entity($pos)))
394
- {
395
- translate_text($start);
396
- $pos++;
397
- $start = $end_of_entity;
398
- }
399
- else
400
- {
401
- $pos++;
402
- }
403
- }
404
-
405
- if($pos > $start)
406
- {
407
- translate_text($start);
408
- }
409
- }
410
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  }
412
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
 
414
  /*
415
  * Determine if the current position in buffer is a sentence breaker, e.g. '.' or ',' .
@@ -418,68 +505,72 @@ function process_current_tag()
418
  */
419
  function is_sentence_breaker($position)
420
  {
421
- global $page;
422
- $rc = FALSE;
423
-
424
- if($page[$position] == '.' || $page[$position] == '-')
425
- {
426
- //Only break if the next character is a white space,
427
- //in order to avoid breaks on cases like this: (hello world.)
428
- if(is_white_space($position + 1) || $page[$position + 1] == '<')
429
- {
430
- $rc = TRUE;
431
- }
432
- }
433
- else if($page[$position] == ',' || $page[$position] == '?' ||
434
- $page[$position] == '(' || $page[$position] == ')' ||
435
- $page[$position] == '[' || $page[$position] == ']' ||
436
- $page[$position] == '"' || $page[$position] == '!' ||
437
- $page[$position] == ':' || $page[$position] == '|')
438
- {
439
- //break the sentence into segments regardless of the next character.
440
- $rc = TRUE;
441
- }
442
-
443
- return $rc;
 
 
 
444
  }
445
 
446
  /*
447
  * Determines if the current position marks the begining of an html
448
  * entity. E.g &amp;
449
- * Return 0 if not an html entity otherwise return the position past this
450
- * entity.
451
  *
452
  */
453
- function is_html_entity($position)
454
  {
455
- global $page;
456
- if($page[$position] == "&" )
457
- {
458
- $end_pos = $position + 1;
459
-
460
- while($page[$end_pos] == "#" ||
461
- is_digit($end_pos) || is_a_to_z_character($end_pos))
462
- {
463
- $end_pos++;
464
- }
465
-
466
- if($page[$end_pos] == ';')
467
- {
468
- $entity = substr($page, $position, $end_pos - $position + 1);
469
-
470
- //Don't break on ` so for our use we don't consider it an entity
471
- //e.g. Jack`s apple
472
- if($entity == "&#8217;" || $entity == "&apos;")
473
- {
474
- return 0;
475
- }
476
-
477
- //It is an html entity.
478
- return $end_pos + 1;
479
- }
480
- }
481
-
482
- return 0;
 
483
  }
484
 
485
 
@@ -492,15 +583,15 @@ function is_html_entity($position)
492
 
493
  function is_a_to_z_character($position)
494
  {
495
- global $page;
496
-
497
- if(($page[$position] >= 'a' && $page[$position] <= 'z') ||
498
- ($page[$position] >= 'A' && $page[$position] <= 'Z'))
499
- {
500
- return TRUE;
501
- }
502
-
503
- return FALSE;
504
  }
505
 
506
  /*
@@ -509,119 +600,165 @@ function is_a_to_z_character($position)
509
  */
510
  function is_digit($position)
511
  {
512
- global $page;
513
-
514
- if($page[$position] >= '0' && $page[$position] <= '9')
515
- {
516
- return TRUE;
517
- }
518
-
519
- return FALSE;
520
  }
521
-
522
  /*
523
- * Determine if the current position in buffer is a white space.
524
  * return TRUE if current position marks a white space otherwise FALSE.
525
- */
526
  function is_white_space($position)
527
  {
528
- global $page;
529
-
530
- if($page[$position] == " " || $page[$position] == "" ||
531
- $page[$position] == "\t" || $page[$position] == "\r" ||
532
- $page[$position] == "\n" || $page[$position] == "\x0B" ||
533
- $page[$position] == "\0")
534
- {
535
- return TRUE;
536
- }
537
  }
538
 
539
  /*
540
  * Skip within buffer past unreadable characters , i.e. white space
541
  * and characters considred to be a sentence breaker. Staring from the specified
542
- * position going either forward or backward.
543
- * param forward - indicate direction going either backward of forward.
544
  */
545
  function skip_unreadable_chars(&$index, $forward=TRUE)
546
  {
547
- global $page, $pos;
548
-
549
- if(!isset($index))
550
- {
551
- //use $pos as the default position if not specified otherwise
552
- $index = &$pos;
553
- }
554
- $start = $index;
555
-
556
- while($index < strlen($page) && $index > 0 &&
557
- (is_white_space($index) || is_sentence_breaker($index)))
558
- {
559
- ($forward ? $index++ : $index--);
560
- }
561
-
562
- return $index;
563
  }
564
 
565
  /*
566
  * Skip within buffer past white space characters , Staring from the specified
567
- * position going either forward or backward.
568
- * param forward - indicate direction going either backward of forward.
569
  */
570
  function skip_white_space(&$index, $forward=TRUE)
571
  {
572
- global $page, $pos;
573
 
574
- if(!isset($index))
575
- {
576
- //use $pos as the default position if not specified otherwise
577
- $index = &$pos;
578
- }
579
 
580
- while($index < strlen($page) && $index > 0 && is_white_space($index))
581
- {
582
- ($forward ? $index++ : $index--);
583
- }
584
 
585
- return $index;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
  }
587
 
 
588
  /**
589
  * Translate the text between the given start position and the current
590
- * position (pos) within the buffer.
591
  */
592
  function translate_text($start)
593
  {
594
-
595
- global $page, $pos, $is_edit_mode;
596
-
597
- //trim white space from the start position going forward
598
- skip_white_space($start);
599
-
600
- //Set the end position of the string to one back from current position
601
- //(i.e. current position points to '<' or a breaker '.') and then trim
602
- //white space from the right backwards
603
- $end = $pos - 1;
604
- $end = skip_white_space($end, $forward=FALSE);
605
-
606
- if($start >= $end)
607
- {
608
- //empty string - nothing to do
609
- return;
610
- }
611
-
612
- $original_text = substr($page, $start, $end - $start + 1);
613
-
614
- //Cleanup and prepare text
615
- $original_text = scrub_text($original_text);
616
- if($original_text == NULL)
617
- {
618
- //nothing left from the text
619
- return;
620
- }
621
-
622
- $translated_text = fetch_translation($original_text);
623
-
624
- insert_translation($original_text, $translated_text, $start, $end);
625
  }
626
 
627
  /*
@@ -633,46 +770,46 @@ function translate_text($start)
633
  */
634
  function insert_translation(&$original_text, &$translated_text, $start, $end)
635
  {
636
- global $segment_id, $is_edit_mode, $tags_list;
637
-
638
- $is_translated = FALSE;
639
-
640
- if(!$is_edit_mode || !in_array('body', $tags_list))
641
- {
642
- if($translated_text != NULL)
643
- {
644
- update_translated_page($start, $end, $translated_text);
645
- }
646
- }
647
- else
648
- {
649
- $span = "<span id=\"" . SPAN_PREFIX . "$segment_id\">";
650
-
651
- if($translated_text == NULL)
652
- {
653
- $span .= $original_text . '</span>';
654
- }
655
- else
656
- {
657
- $span .= $translated_text . "</span>";
658
- $is_translated = TRUE;
659
- }
660
-
661
- //Insert text (either original or translated) marked by a <span>
662
- update_translated_page($start, $end, $span);
663
-
664
-
665
- //Insert image to allow editing this segment
666
- $img = get_img_tag($original_text, $translated_text, $segment_id, $is_translated);
667
- update_translated_page($end + 1, - 1, $img);
668
-
669
- //Increment only after both text and image are generated so they
670
- //will be the same for each translated segement
671
- $segment_id++;
672
-
673
- }
674
-
675
-
676
  }
677
 
678
 
@@ -683,17 +820,17 @@ function insert_translation(&$original_text, &$translated_text, $start, $end)
683
  */
684
  function scrub_text(&$text)
685
  {
686
- //skip strings like without any readable characters (i.e. ".")
687
- //Todo: need a broader defintion for non-ascii characters as well
688
- if(preg_match("/^[.?!|\(\)\[\],0-9]+$/", $text))
689
- {
690
- return NULL;
691
- }
692
 
693
- //replace multi space chars with a single space
694
- $text = preg_replace("/\s\s+/", " ", $text);
695
 
696
- return $text;
697
  }
698
 
699
 
@@ -703,29 +840,29 @@ function scrub_text(&$text)
703
  * back in buffer.
704
  * param start - marks the starting position of the replaced string in the original page.
705
  * param end - marks the end position of the replaced string in the original page.
706
- Use -1 to do insert instead of replace.
707
  * param translated_text - text to be inserted.
708
  */
709
  function update_translated_page($start, $end, $translated_text)
710
  {
711
- global $page, $tr_page, $tr_mark;
712
-
713
- //Bring the translated up to date up to the start position.
714
- while($tr_mark < $start)
715
- {
716
- $tr_page .= $page[$tr_mark++];
717
- }
718
-
719
- $tr_page .= $translated_text;
720
-
721
- if($end > $start)
722
- {
723
- //Move mark to correlate the posistion between the two pages.
724
- //Only do this when some content has been replaced, i.e. not
725
- //an insert.
726
- $tr_mark = $end + 1;
727
- }
728
-
729
  }
730
 
731
  ?>
20
  * Contains the core functionality of the html parser. I.e. break into translation segments,
21
  * fetch translation and update the translated page.
22
  * This file should include only general purpose parser functionality while using callbacks
23
+ * to obtain WorkdPress specific capabilities, e.g. db access.
24
  */
25
 
26
 
27
  require_once("constants.php");
28
 
29
+ //The language to which the current page will be translated to.
30
  $lang;
31
+
32
  //The html page which starts contains the content being translated
33
  $page;
34
+
35
  //Marks the current position of the translation process within the page
36
  $pos = 0;
37
 
38
  //Contains the stack of tag in the current position within the page
39
  $tags_list = array();
40
 
41
+ //The translated html page
42
  $tr_page;
43
+
44
+ //Points to the last character that have been copied from the original to the translated page.
45
  $tr_mark = 0;
46
 
47
+ //Is the current use is in edit mode.
48
  $is_edit_mode = FALSE;
49
 
50
  //Segment identifier within tags (span/img) mainly for use by js code on the client
53
  //Is current position within the body tag
54
  $is_in_body = FALSE;
55
 
56
+ //Is current position within the channel tag, i.e. RSS feed
57
+ $is_in_channel = FALSE;
58
+
59
  /*
60
  * Parse the html page into tags, identify translateable string which
61
+ * will be translated.
62
  */
63
  function process_html()
64
  {
65
+
66
+
67
+ global $page, $tr_page, $pos, $tags_list, $lang;
68
+ $no_translate = 0;
69
+ $page_length = strlen($page);
70
+
71
+ while($pos < $page_length)
72
+ {
73
+ //find beginning of next tag
74
+ $pos = strpos($page, '<', $pos);
75
+ if($pos === FALSE)
76
+ {
77
+ //
78
+ break;
79
+ }
80
+ $pos++;
81
+
82
+ //Get the element identifying this tag
83
+ $element = get_element();
84
+
85
+ if(should_skip_element($element))
86
+ {
87
+
88
+ //do nothing
89
+ }
90
+ else if($element == '![CDATA[')
91
+ {
92
+ process_cdata_section();
93
+ }
94
+ else
95
+ {
96
+ //Mark tag start position
97
+ $tag_start = $pos;
98
+ $pos = strpos($page, '>', $pos);
99
+
100
+ //Mark tag end position
101
+ $tag_end = $pos;
102
+
103
+ if($page[$pos-1] == '/')
104
+ {
105
+ //single line tag - no need to update tags list
106
+ process_tag_init($element, $tag_start, $tag_end);
107
+ }
108
+ else if($element[0] != '/')
109
+ {
110
+ if(!$no_translate)
111
+ {
112
+ process_tag_init($element, $tag_start, $tag_end);
113
+ }
114
+
115
+ $tags_list[] = $element;
116
+
117
+ //Look for the no translate class
118
+ if(stripos($element, NO_TRANSLATE_CLASS) !== FALSE)
119
+ {
120
+ $no_translate++;
121
+ }
122
+ }
123
+ else
124
+ {
125
+ $popped_element = array_pop($tags_list);
126
+ if(!$no_translate)
127
+ {
128
+ process_tag_termination($element);
129
+ }
130
+
131
+ //Look for the no translate class
132
+ if(stripos($popped_element, NO_TRANSLATE_CLASS) !== FALSE)
133
+ {
134
+ $no_translate--;
135
+ }
136
+ }
137
+
138
+ $pos++;
139
+
140
+ //skip processing while enclosed within a tag marked by no_translate
141
+ if(!$no_translate)
142
+ {
143
+ process_current_tag();
144
+ }
145
+
146
+ }
147
+ }
148
+
149
+ if(strlen($tr_page) > 0)
150
+ {
151
+ //Some translation has been taken place. Complete the translated
152
+ //page up to the full contents of the original page.
153
+ update_translated_page(strlen($page), -1, "");
154
+ }
155
+
156
+
157
  }
158
 
159
 
160
  /*
161
  * Determine if the specified element should be skipped. If so the position
162
  * is moved past end of tag.
163
+ * Return TRUE if element is skipped otherwise FALSE.
164
  */
165
  function should_skip_element(&$element)
166
  {
167
+ global $page, $pos;
168
+ $rc = TRUE;
169
+
170
+ if(strncmp($element, "!DOCTYPE", 8) == 0)
171
+ {
172
+ $pos = strpos($page, '>', $pos);
173
+ }
174
+ else if(strncmp($element, "!--", 3) == 0)
175
+ {
176
+ $pos = strpos($page, '-->', $pos);
177
+ }
178
+ else
179
+ {
180
+ $rc = FALSE;
181
+ }
182
+
183
+ return $rc;
184
  }
185
 
186
  /*
189
  */
190
  function process_tag_init(&$element, $start, $end)
191
  {
192
+ switch ($element)
193
+ {
194
+ case 'a':
195
+ process_anchor_tag($start, $end);
196
+ break;
197
+ case 'div' :
198
+ case 'span':
199
+ process_span_or_div_tag($element, $start, $end);
200
+ break;
201
+ case 'html':
202
+ process_html_tag($start, $end);
203
+ break;
204
+ case 'body':
205
+ global $is_in_body;
206
+ $is_in_body = TRUE;
207
+ break;
208
+ case 'channel':
209
+ global $is_in_channel;
210
+ $is_in_channel = TRUE;
211
+ break;
212
+ }
213
+
214
  }
215
 
216
 
221
  */
222
  function process_span_or_div_tag(&$element, $start, $end)
223
  {
224
+
225
+ $cls = get_attribute($start, $end, 'class');
226
+
227
+ if($cls == NULL)
228
+ {
229
+ return;
230
+ }
231
+
232
+ //Look for the no translate class
233
+ if(stripos($cls, NO_TRANSLATE_CLASS) === FALSE)
234
+ {
235
+ return;
236
+ }
237
+
238
+ //Mark the element as not translatable
239
+ $element .= "." . NO_TRANSLATE_CLASS;
240
  }
241
 
242
 
243
  /*
244
+ * Process html tag. Set the direction for rtl languages.
245
  *
246
  */
247
  function process_html_tag($start, $end)
248
  {
249
+ global $lang, $rtl_languages;
250
+
251
+ if(!(in_array ($lang, $rtl_languages)))
252
+ {
253
+ return;
254
+ }
255
+
256
+ $dir = get_attribute($start, $end, 'dir');
257
+
258
+ if($dir == NULL)
259
+ {
260
+
261
+ //attribute does not exist - add it
262
+ update_translated_page($end, -1, 'dir="rtl"');
263
+ }
264
+ else
265
+ {
266
+ $dir = 'rtl';
267
+
268
+ //rewrite url in translated page
269
+ update_translated_page($start, $end, $dir);
270
+
271
+ }
272
+
273
  }
274
 
275
 
279
  */
280
  function process_tag_termination(&$element)
281
  {
282
+ global $pos, $tags_list, $page;
283
+
284
+
285
  }
286
 
287
 
288
  /*
289
+ * Return the element id within the current tag.
290
  */
291
  function get_element()
292
  {
293
+ global $page, $pos;
294
+
295
+
296
+ skip_white_space();
297
+
298
+ $start = $pos;
299
+
300
+ //check first for a character data section - treat it like an element
301
+ if(is_word('![CDATA['))
302
+ {
303
+ $pos += 8; //skip to end of ![CDATA[
304
+ }
305
+ else
306
+ {
307
+ //keep scanning till the first white space or the '>' mark
308
+ while($pos < strlen($page) && !is_white_space($pos) && $page[$pos] != '>')
309
+ {
310
+ $pos++;
311
+ }
312
+ }
313
+
314
+
315
+ return substr($page,$start, $pos - $start);
316
  }
317
 
318
  /*
320
  * end position within the buffer.
321
  * Returns the string containing the attribute if available otherwise NULL.
322
  * In addition the start and end position are moved to boundaries of the
323
+ * attribute's value.
324
  */
325
  function get_attribute(&$start, &$end, $id)
326
  {
327
+ global $page;
328
+
329
+ //look for the id within the given limits.
330
+ while($start < $end)
331
+ {
332
+ $index = 0;
333
+
334
+ while($start < $end && $page[$start + $index] == $id[$index]
335
+ && $index < strlen($id))
336
+ {
337
+ $index++;
338
+ }
339
+
340
+ if($index == strlen($id))
341
+ {
342
+ //we have match
343
+ break;
344
+ }
345
+
346
+ $start++;
347
+ }
348
+
349
+ if($start == $end)
350
+ {
351
+ return NULL;
352
+ }
353
+
354
+ //look for the " or ' marking start of attribute's value
355
+ while($start < $end && $page[$start] != '"' && $page[$start] != "'")
356
+ {
357
+ $start++;
358
+ }
359
+
360
+ $start++;
361
+ if($start >= $end)
362
+ {
363
+ return NULL;
364
+ }
365
+
366
+ $tmp = $start + 1;
367
+ //look for the " or ' marking the end of attribute's value
368
+ while($tmp < $end && $page[$tmp] != '"' && $page[$tmp] != "'")
369
+ {
370
+ $tmp++;
371
+ }
372
+
373
+ $end = $tmp - 1;
374
+
375
+
376
+ return substr($page, $start, $end - $start + 1);
377
  }
378
 
379
  /*
383
  */
384
  function process_current_tag()
385
  {
386
+ global $page, $pos;
387
+
388
+
389
+
390
+ //translate only known elements within the body or channel
391
+ if(is_translatable_section())
392
+ {
393
+ skip_white_space();
394
+ $start = $pos;
395
+ $page_length = strlen($page);
396
+
397
+ // Indicates if the html entity should break into a new translation segment.
398
+ $is_breaker = FALSE;
399
+
400
+ while($pos < $page_length && $page[$pos] != '<')
401
+ {
402
+ //will break translation unit when one of the following characters is reached: .,
403
+ if(($end_of_entity = is_html_entity($pos, $is_breaker)))
404
+ {
405
+ //Check if should break - value has been set by the is_html_entity function
406
+ if($is_breaker)
407
+ {
408
+ translate_text($start);
409
+ $start = $end_of_entity;
410
+ }
411
+
412
+ //skip past entity
413
+ $pos = $end_of_entity;
414
+ }
415
+ else if(is_sentence_breaker($pos))
416
+ {
417
+ translate_text($start);
418
+ $pos++;
419
+ $start = $pos;
420
+ }
421
+ else
422
+ {
423
+ $pos++;
424
+ }
425
+ }
426
+
427
+ if($pos > $start)
428
+ {
429
+ translate_text($start);
430
+ }
431
+ }
432
+
433
+ }
434
+
435
+
436
+ /*
437
+ * Translate the content of a cdata section. For now we only expect to handle it
438
+ * within RSS feeds.
439
+ */
440
+ function process_cdata_section()
441
+ {
442
+ global $page, $pos;
443
+
444
+
445
+
446
+ //translate only known elements within rss feeds
447
+ if(is_translatable_section())
448
+ {
449
+ skip_white_space();
450
+ $start = $pos;
451
+ $page_length = strlen($page);
452
+
453
+ while($pos < $page_length && !is_word(']]>'))
454
+ {
455
+ //will break translation unit when one of the following characters is reached: .,
456
+ if(is_sentence_breaker($pos) ||
457
+ $page[$pos] == '<' || $page[$pos] == '>') //only in cdata the < > are valid breakers as well
458
+ {
459
+ translate_text($start);
460
+ $pos++;
461
+ $start = $pos;
462
+ }
463
+ else
464
+ {
465
+ $pos++;
466
+ }
467
+ }
468
+
469
+ if($pos > $start)
470
+ {
471
+ translate_text($start);
472
+ }
473
+ }
474
+
475
  }
476
 
477
+ /**
478
+ * Determines position in page marks a transaltable tag in html page or rss feed section.
479
+ * Return TRUE if should be translated otherwise FALSE.
480
+ */
481
+ function is_translatable_section()
482
+ {
483
+ global $tags_list, $is_in_channel, $is_in_body;
484
+ $rc = FALSE;
485
+ $current_tag = end($tags_list);
486
+
487
+ if($is_in_body || $current_tag == 'title')
488
+ {
489
+ $rc = TRUE;
490
+ }
491
+ else if($is_in_channel &&
492
+ ($current_tag == 'title' || $current_tag == 'description' || $current_tag == 'category'))
493
+ {
494
+ $rc = TRUE;
495
+ }
496
+
497
+
498
+ return $rc;
499
+ }
500
 
501
  /*
502
  * Determine if the current position in buffer is a sentence breaker, e.g. '.' or ',' .
505
  */
506
  function is_sentence_breaker($position)
507
  {
508
+ global $page;
509
+ $rc = FALSE;
510
+
511
+ if($page[$position] == '.' || $page[$position] == '-')
512
+ {
513
+ //Only break if the next character is a white space,
514
+ //in order to avoid breaks on cases like this: (hello world.)
515
+ if(is_white_space($position + 1) || $page[$position + 1] == '<')
516
+ {
517
+ $rc = TRUE;
518
+ }
519
+ }
520
+ else if($page[$position] == ',' || $page[$position] == '?' ||
521
+ $page[$position] == '(' || $page[$position] == ')' ||
522
+ $page[$position] == '[' || $page[$position] == ']' ||
523
+ $page[$position] == '"' || $page[$position] == '!' ||
524
+ $page[$position] == ':' || $page[$position] == '|' ||
525
+ $page[$position] == ';' ||
526
+ //break on numbers but not like: 3rd, 4th
527
+ (is_digit($position) && !is_a_to_z_character($position+1)))
528
+ {
529
+ //break the sentence into segments regardless of the next character.
530
+ $rc = TRUE;
531
+ }
532
+
533
+ return $rc;
534
  }
535
 
536
  /*
537
  * Determines if the current position marks the begining of an html
538
  * entity. E.g &amp;
539
+ * Return 0 if not an html entity otherwise return the position past this entity. In addition
540
+ * the $is_breaker will be set to TRUE if entity should break translation into a new segment.
541
  *
542
  */
543
+ function is_html_entity($position, &$is_breaker)
544
  {
545
+ global $page;
546
+ $is_breaker = FALSE;
547
+ if($page[$position] == "&" )
548
+ {
549
+ $end_pos = $position + 1;
550
+
551
+ while($page[$end_pos] == "#" ||
552
+ is_digit($end_pos) || is_a_to_z_character($end_pos))
553
+ {
554
+ $end_pos++;
555
+ }
556
+
557
+ if($page[$end_pos] == ';')
558
+ {
559
+ $entity = substr($page, $position, $end_pos - $position + 1);
560
+
561
+ //Don't break on ` so for our use we don't consider it an entity
562
+ //e.g. Jack`s apple
563
+ if(!($entity == "&#8217;" || $entity == "&apos;" || $entity == "&#039;"))
564
+ {
565
+ $is_breaker = TRUE;
566
+ }
567
+
568
+ //It is an html entity.
569
+ return $end_pos + 1;
570
+ }
571
+ }
572
+
573
+ return 0;
574
  }
575
 
576
 
583
 
584
  function is_a_to_z_character($position)
585
  {
586
+ global $page;
587
+
588
+ if(($page[$position] >= 'a' && $page[$position] <= 'z') ||
589
+ ($page[$position] >= 'A' && $page[$position] <= 'Z'))
590
+ {
591
+ return TRUE;
592
+ }
593
+
594
+ return FALSE;
595
  }
596
 
597
  /*
600
  */
601
  function is_digit($position)
602
  {
603
+ global $page;
604
+
605
+ if($page[$position] >= '0' && $page[$position] <= '9')
606
+ {
607
+ return TRUE;
608
+ }
609
+
610
+ return FALSE;
611
  }
612
+
613
  /*
614
+ * Determine if the current position in buffer is a white space.
615
  * return TRUE if current position marks a white space otherwise FALSE.
616
+ */
617
  function is_white_space($position)
618
  {
619
+ global $page;
620
+
621
+ if($page[$position] == " " || $page[$position] == "" ||
622
+ $page[$position] == "\t" || $page[$position] == "\r" ||
623
+ $page[$position] == "\n" || $page[$position] == "\x0B" ||
624
+ $page[$position] == "\0")
625
+ {
626
+ return TRUE;
627
+ }
628
  }
629
 
630
  /*
631
  * Skip within buffer past unreadable characters , i.e. white space
632
  * and characters considred to be a sentence breaker. Staring from the specified
633
+ * position going either forward or backward.
634
+ * param forward - indicate direction going either backward of forward.
635
  */
636
  function skip_unreadable_chars(&$index, $forward=TRUE)
637
  {
638
+ global $page, $pos;
639
+
640
+ if(!isset($index))
641
+ {
642
+ //use $pos as the default position if not specified otherwise
643
+ $index = &$pos;
644
+ }
645
+ $start = $index;
646
+
647
+ while($index < strlen($page) && $index > 0 &&
648
+ (is_white_space($index) || is_sentence_breaker($index)))
649
+ {
650
+ ($forward ? $index++ : $index--);
651
+ }
652
+
653
+ return $index;
654
  }
655
 
656
  /*
657
  * Skip within buffer past white space characters , Staring from the specified
658
+ * position going either forward or backward.
659
+ * param forward - indicate direction going either backward of forward.
660
  */
661
  function skip_white_space(&$index, $forward=TRUE)
662
  {
663
+ global $page, $pos;
664
 
665
+ if(!isset($index))
666
+ {
667
+ //use $pos as the default position if not specified otherwise
668
+ $index = &$pos;
669
+ }
670
 
671
+ while($index < strlen($page) && $index > 0 && is_white_space($index))
672
+ {
673
+ ($forward ? $index++ : $index--);
674
+ }
675
 
676
+ return $index;
677
+ }
678
+
679
+
680
+ /*
681
+ * Check within page buffer position for the given word.
682
+ * param word The word to look for.
683
+ * param index1 Optional position within the page buffer, if not available then the current
684
+ * position ($pos) is used.
685
+ * Return TRUE if the word matches otherwise FALSE
686
+ */
687
+ function is_word($word, $index1)
688
+ {
689
+ global $page, $pos;
690
+ $rc = FALSE;
691
+
692
+ if(!isset($index1))
693
+ {
694
+ //use $pos as the default position if not specified otherwise
695
+ $index1 = $pos;
696
+ }
697
+
698
+ $index2 = 0; //position within word
699
+ $word_len = strlen($word);
700
+ $page_length = strlen($page);
701
+
702
+ while($index1 < $page_length && $index2 < $word_len)
703
+ {
704
+ if($page[$index1] == $word[$index2])
705
+ {
706
+ $index1++;
707
+ $index2++;
708
+ }
709
+ else
710
+ {
711
+ break;
712
+ }
713
+ }
714
+
715
+ //check if we have full match
716
+ if($index2 == $word_len)
717
+ {
718
+ $rc = TRUE;
719
+ }
720
+
721
+ return $rc;
722
  }
723
 
724
+
725
  /**
726
  * Translate the text between the given start position and the current
727
+ * position (pos) within the buffer.
728
  */
729
  function translate_text($start)
730
  {
731
+
732
+ global $page, $pos, $is_edit_mode;
733
+
734
+ //trim white space from the start position going forward
735
+ skip_white_space($start);
736
+
737
+ //Set the end position of the string to one back from current position
738
+ //(i.e. current position points to '<' or a breaker '.') and then trim
739
+ //white space from the right backwards
740
+ $end = $pos - 1;
741
+ $end = skip_white_space($end, $forward=FALSE);
742
+
743
+ if($start >= $end)
744
+ {
745
+ //empty string - nothing to do
746
+ return;
747
+ }
748
+
749
+ $original_text = substr($page, $start, $end - $start + 1);
750
+
751
+ //Cleanup and prepare text
752
+ $original_text = scrub_text($original_text);
753
+ if($original_text == NULL)
754
+ {
755
+ //nothing left from the text
756
+ return;
757
+ }
758
+
759
+ $translated_text = fetch_translation($original_text);
760
+
761
+ insert_translation($original_text, $translated_text, $start, $end);
762
  }
763
 
764
  /*
770
  */
771
  function insert_translation(&$original_text, &$translated_text, $start, $end)
772
  {
773
+ global $segment_id, $is_edit_mode, $tags_list;
774
+
775
+ $is_translated = FALSE;
776
+
777
+ if(!$is_edit_mode || !in_array('body', $tags_list))
778
+ {
779
+ if($translated_text != NULL)
780
+ {
781
+ update_translated_page($start, $end, $translated_text);
782
+ }
783
+ }
784
+ else
785
+ {
786
+ $span = "<span id=\"" . SPAN_PREFIX . "$segment_id\">";
787
+
788
+ if($translated_text == NULL)
789
+ {
790
+ $span .= $original_text . '</span>';
791
+ }
792
+ else
793
+ {
794
+ $span .= $translated_text . "</span>";
795
+ $is_translated = TRUE;
796
+ }
797
+
798
+ //Insert text (either original or translated) marked by a <span>
799
+ update_translated_page($start, $end, $span);
800
+
801
+
802
+ //Insert image to allow editing this segment
803
+ $img = get_img_tag($original_text, $translated_text, $segment_id, $is_translated);
804
+ update_translated_page($end + 1, - 1, $img);
805
+
806
+ //Increment only after both text and image are generated so they
807
+ //will be the same for each translated segement
808
+ $segment_id++;
809
+
810
+ }
811
+
812
+
813
  }
814
 
815
 
820
  */
821
  function scrub_text(&$text)
822
  {
823
+ //skip strings like without any readable characters (i.e. ".")
824
+ //Todo: need a broader defintion for non-ascii characters as well
825
+ if(preg_match("/^[.?!|\(\)\[\],0-9]+$/", $text))
826
+ {
827
+ return NULL;
828
+ }
829
 
830
+ //replace multi space chars with a single space
831
+ $text = preg_replace("/\s\s+/", " ", $text);
832
 
833
+ return $text;
834
  }
835
 
836
 
840
  * back in buffer.
841
  * param start - marks the starting position of the replaced string in the original page.
842
  * param end - marks the end position of the replaced string in the original page.
843
+ Use -1 to do insert instead of replace.
844
  * param translated_text - text to be inserted.
845
  */
846
  function update_translated_page($start, $end, $translated_text)
847
  {
848
+ global $page, $tr_page, $tr_mark;
849
+
850
+ //Bring the translated up to date up to the start position.
851
+ while($tr_mark < $start)
852
+ {
853
+ $tr_page .= $page[$tr_mark++];
854
+ }
855
+
856
+ $tr_page .= $translated_text;
857
+
858
+ if($end > $start)
859
+ {
860
+ //Move mark to correlate the posistion between the two pages.
861
+ //Only do this when some content has been replaced, i.e. not
862
+ //an insert.
863
+ $tr_mark = $end + 1;
864
+ }
865
+
866
  }
867
 
868
  ?>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://transposh.org/
4
  Tags: translation, widget, filter, bilingual, multilingual, transposh, language, RTL, Hebrew, Spanish, French, Russian, crowdsourcing, context, wiki
5
  Requires at least: 2.5
6
  Tested up to: 2.7.1
7
- Stable tag: 0.0.2
8
 
9
  Transposh filter allows in context quick translation of websites, it allows you to crowd-source the translation to your users
10
 
@@ -71,8 +71,11 @@ harnessed to get your message out to more people. Future versions will give more
71
 
72
  == Release notes ==
73
 
74
- * 09/03/01 - 0.0.2
 
 
 
75
  * Fixed bug with hard coded plugin path (thanks [Atomboy](http://politicalnewsblogs.com/))
76
  * Support for AJAX replacement of content using jQuery
77
- * 09/02/28 - 0.0.1
78
  * Initial release
4
  Tags: translation, widget, filter, bilingual, multilingual, transposh, language, RTL, Hebrew, Spanish, French, Russian, crowdsourcing, context, wiki
5
  Requires at least: 2.5
6
  Tested up to: 2.7.1
7
+ Stable tag: 0.0.3
8
 
9
  Transposh filter allows in context quick translation of websites, it allows you to crowd-source the translation to your users
10
 
71
 
72
  == Release notes ==
73
 
74
+ * 2009/03/07 - 0.0.3
75
+ * Added ability to get suggestions from Google Translate
76
+ * Improved support for RSS feeds translation
77
+ * 2009/03/01 - 0.0.2
78
  * Fixed bug with hard coded plugin path (thanks [Atomboy](http://politicalnewsblogs.com/))
79
  * Support for AJAX replacement of content using jQuery
80
+ * 2009/02/28 - 0.0.1
81
  * Initial release
transposh.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin URI: http://transposh.org/#
5
  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>.
6
  Author: Team Transposh
7
- Version: 0.0.2
8
  Author URI: http://transposh.org/
9
  License: GPL (http://www.gnu.org/licenses/gpl.txt)
10
  */
@@ -61,7 +61,7 @@ $home_url_quoted;
61
 
62
  //The url pointing to the base of the plugin
63
  $plugin_url;
64
-
65
  //Error message displayed for the admin in case of failure
66
  $admin_msg;
67
 
@@ -69,20 +69,20 @@ $admin_msg;
69
  /*
70
  * Called when the buffer containing the original page is flused. Triggers the
71
  * translation process.
72
- *
73
- */
74
  function process_page(&$buffer) {
75
-
76
  global $wp_query, $tr_page, $page, $pos, $lang, $plugin_url, $is_edit_mode, $wpdb,
77
  $table_name;
78
-
79
  $start_time = microtime(TRUE);
80
-
81
  if (!isset($wp_query->query_vars[LANG_PARAM]))
82
  {
83
  //No language code - avoid further processing.
84
  return $buffer;
85
-
86
  }
87
 
88
  $lang = $wp_query->query_vars[LANG_PARAM];
@@ -93,8 +93,8 @@ function process_page(&$buffer) {
93
 
94
  return $buffer;
95
  }
96
-
97
-
98
  $page = $buffer;
99
 
100
 
@@ -104,36 +104,36 @@ function process_page(&$buffer) {
104
  //Verify that the current language is editable and that the
105
  //user has the required permissions
106
  $editable_langs = get_option(EDITABLE_LANGS);
107
-
108
  if(is_translator() && strstr($editable_langs, $lang))
109
  {
110
  $is_edit_mode = TRUE;
111
  }
112
-
113
  }
 
114
 
115
-
116
-
117
  //translate the entire page
118
  process_html();
119
-
120
  $end_time = microtime(TRUE);
121
 
122
 
123
-
124
  //return the translated page unless it is empty, othewise return the original
125
  return (strlen($tr_page) > 0 ? $tr_page : $page);
126
  }
127
 
128
  /*
129
  * Fix links on the page. href needs to be modified to include
130
- * lang specifier and editing mode.
131
  *
132
  */
133
  function process_anchor_tag($start, $end)
134
  {
135
  global $home_url, $home_url_quoted, $lang, $is_edit_mode, $wp_rewrite;
136
-
137
  $href = get_attribute($start, $end, 'href');
138
 
139
  if($href == NULL)
@@ -148,11 +148,11 @@ function process_anchor_tag($start, $end)
148
  }
149
 
150
  $use_params = FALSE;
151
-
152
- //Only use params if permalinks are not enabled.
153
  //don't fix links pointing to real files as it will cause that the
154
  //web server will not be able to locate them
155
- if(!$wp_rewrite->using_permalinks() ||
156
  stripos($href, '/wp-admin') !== FALSE ||
157
  stripos($href, '/wp-content') !== FALSE ||
158
  stripos($href, '/wp-login') !== FALSE ||
@@ -170,7 +170,7 @@ function process_anchor_tag($start, $end)
170
 
171
 
172
  /*
173
- * Update the given url to include language params.
174
  * param url - the original url to rewrite
175
  * param lang - language code
176
  * param is_edit - is running in edit mode.
@@ -185,11 +185,11 @@ function rewrite_url_lang_param($url, $lang, $is_edit, $use_params_only)
185
  //override the use only params - admin configured system to not touch permalinks
186
  $use_params_only = TRUE;
187
  }
188
-
189
  if($is_edit)
190
  {
191
  $params = EDIT_PARAM . '=1&';
192
-
193
  }
194
 
195
  if($use_params_only)
@@ -209,7 +209,7 @@ function rewrite_url_lang_param($url, $lang, $is_edit, $use_params_only)
209
 
210
  //Cleanup extra &
211
  $url = preg_replace("/&&+/", "&", $url);
212
-
213
  //Cleanup extra ?
214
  $url = preg_replace("/\?\?+/", "?", $url);
215
  }
@@ -218,36 +218,37 @@ function rewrite_url_lang_param($url, $lang, $is_edit, $use_params_only)
218
  }
219
 
220
  /*
221
- * Fetch translation from db or cache.
222
  * Returns the translated string or NULL if not available.
223
  */
224
  function fetch_translation($original)
225
  {
226
  global $wpdb, $lang, $table_name;
227
  $translated = NULL;
228
-
229
 
230
  if(ENABLE_APC && function_exists('apc_fetch'))
231
  {
232
  $cached = apc_fetch($original . $lang, $rc);
233
  if($rc === TRUE)
234
  {
235
- return $cached;
 
236
  }
237
  }
238
-
239
- $query = "SELECT * FROM $table_name WHERE original = '$original' and lang = '$lang' ";
240
  $row = $wpdb->get_row($query);
241
-
242
  if($row !== FALSE)
243
  {
244
  $translated = $row->translated;
245
  $translated = stripslashes($translated);
246
-
247
 
248
  }
249
-
250
-
251
  if(ENABLE_APC && function_exists('apc_store'))
252
  {
253
  //If we don't have translation still we want to have it in cache
@@ -256,7 +257,7 @@ function fetch_translation($original)
256
  {
257
  $cache_entry = "";
258
  }
259
-
260
  //update cache
261
  $rc = apc_store($original . $lang, $cache_entry, 3600);
262
  if($rc === TRUE)
@@ -264,7 +265,7 @@ function fetch_translation($original)
264
 
265
  }
266
  }
267
-
268
 
269
  return $translated;
270
  }
@@ -276,10 +277,19 @@ function fetch_translation($original)
276
  */
277
  function insert_javascript_includes()
278
  {
279
- global $plugin_url;
 
 
 
 
 
 
 
 
280
 
 
281
  $overlib_dir = "$plugin_url/js/overlibmws";
282
-
283
  $js = "\n<script type=\"text/javascript\" src=\"$overlib_dir/overlibmws.js\"></script>";
284
  $js .= "\n<script type=\"text/javascript\" src=\"$overlib_dir/overlibmws_filter.js\"></script>";
285
  $js .= "\n<script type=\"text/javascript\" src=\"$overlib_dir/overlibmws_modal.js\"></script>";
@@ -289,6 +299,8 @@ function insert_javascript_includes()
289
 
290
  $js .= "\n<script type=\"text/javascript\" src=\"$plugin_url/js/transposh.js\"></script>\n";
291
  $js .= "\n<script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js\"></script>\n";
 
 
292
 
293
  echo $js;
294
  }
@@ -296,7 +308,7 @@ function insert_javascript_includes()
296
 
297
  /*
298
  * Return the img tag that will added to enable editing a translatable
299
- * item on the page.
300
  * param segement_id The id (number) identifying this segment. Needs to be
301
  placed within the img tag for use on client side operation (jquery)
302
  */
@@ -304,8 +316,8 @@ function get_img_tag($original, $translation, $segment_id, $is_translated = FALS
304
  {
305
  global $plugin_url, $lang, $home_url;
306
  $url = $home_url . '/index.php';
307
-
308
- //For use in javascript, make the following changes:
309
  //1. Add slashes to escape the inner text
310
  //2. Convert the html special characters
311
  //The browser will take decode step 2 and pass it to the js engine which decode step 1 - a bit tricky
@@ -317,11 +329,11 @@ function get_img_tag($original, $translation, $segment_id, $is_translated = FALS
317
  $add_img = "_fix";
318
  }
319
 
320
- $img = "<img src=\"$plugin_url/translate$add_img.png\" alt=\"translate\" id=\"" . IMG_PREFIX . "$segment_id\"
321
- onclick=\"translate_dialog('$original','$translation','$lang','$url', '$segment_id'); return false;\"
322
- onmouseover=\"hint('$original'); return true;\"
323
  onmouseout=\"nd()\" />";
324
-
325
  return $img;
326
  }
327
 
@@ -345,8 +357,8 @@ function transposh_css()
345
  {
346
  return;
347
  }
348
-
349
- //include the transposh.css
350
  echo "<link rel=\"stylesheet\" href=\"$plugin_url/transposh.css\" type=\"text/css\" />";
351
 
352
 
@@ -358,10 +370,10 @@ function transposh_css()
358
  function init_global_vars()
359
  {
360
  global $home_url, $home_url_quoted, $plugin_url, $table_name, $wpdb;
361
-
362
  $home_url = get_option('home');
363
  $local_dir = preg_replace("/.*\//", "", dirname(__FILE__));
364
-
365
  $plugin_url= $home_url . "/wp-content/plugins/$local_dir";
366
  $home_url_quoted = preg_quote($home_url);
367
  $home_url_quoted = preg_replace("/\//", "\\/", $home_url_quoted);
@@ -371,18 +383,18 @@ function init_global_vars()
371
 
372
 
373
  /*
374
- * A new translation has been posted, update the translation database.
375
  *
376
  */
377
  function update_translation()
378
  {
379
  global $wpdb, $table_name;
380
-
381
  $ref=getenv('HTTP_REFERER');
382
  $original = $_POST['original'];
383
  $translation = $_POST['translation'];
384
  $lang = $_POST['lang'];
385
-
386
  if(!isset($original) || !isset($translation) || !isset($lang))
387
  {
388
  logger("Enter " . __FILE__ . " missing params: $original , $translation, $lang," .
@@ -396,10 +408,10 @@ function update_translation()
396
 
397
  }
398
 
399
- //Decode & remove already escaped character to avoid double escaping
400
  $original = $wpdb->escape(stripslashes(urldecode($original)));
401
  $translation = $wpdb->escape(htmlspecialchars(stripslashes(urldecode($translation))));
402
-
403
  $update = "REPLACE INTO $table_name (original, translated, lang)
404
  VALUES ('" . $original . "','" . $translation . "','" . $lang . "')";
405
 
@@ -454,7 +466,7 @@ function update_transaction_log(&$original, &$translation, &$lang)
454
  {
455
 
456
  }
457
-
458
  }
459
 
460
 
@@ -466,7 +478,7 @@ function update_transaction_log(&$original, &$translation, &$lang)
466
  function get_default_lang()
467
  {
468
  global $languages;
469
-
470
  $default = get_option(DEFAULT_LANG);
471
  if(!$languages[$default])
472
  {
@@ -499,7 +511,7 @@ function on_init()
499
 
500
 
501
  /*
502
- * Page generation completed - flush buffer.
503
  */
504
  function on_shutdown()
505
  {
@@ -519,20 +531,20 @@ function update_rewrite_rules($rules){
519
 
520
  return $rule;
521
  }
522
-
523
  $newRules = array();
524
  $lang_prefix="([a-z]{2,2}(\-[a-z]{2,2})?)/";
525
 
526
  $lang_parameter= "&" . LANG_PARAM . '=$matches[1]';
527
 
528
- //catch the root url
529
  $newRules[$lang_prefix."?$"] = "index.php?lang=\$matches[1]";
530
 
531
 
532
  foreach ($rules as $key=>$value) {
533
  $original_key = $key;
534
  $original_value = $value;
535
-
536
  $key = $lang_prefix . $key;
537
 
538
  //Shift existing matches[i] two step forward as we pushed new elements
@@ -543,9 +555,9 @@ function update_rewrite_rules($rules){
543
  }
544
 
545
  $value .= $lang_parameter;
 
546
 
547
-
548
-
549
 
550
  $newRules[$key] = $value;
551
  $newRules[$original_key] = $original_value;
@@ -570,10 +582,10 @@ function parameter_queryvars($qvars)
570
 
571
 
572
  /*
573
- * Setup the translation database.
574
  *
575
  */
576
- function setup_db()
577
  {
578
 
579
  global $wpdb;
@@ -583,13 +595,13 @@ function setup_db()
583
 
584
  if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name)
585
  {
586
-
587
  $sql = "CREATE TABLE " . $table_name . " (original VARCHAR(256) NOT NULL,
588
  lang CHAR(5) NOT NULL,
589
  translated VARCHAR(256),
590
  PRIMARY KEY (original, lang)) ";
591
-
592
-
593
  dbDelta($sql);
594
 
595
  //Verify that newly created table is ready for use.
@@ -597,14 +609,14 @@ function setup_db()
597
  "VALUES ('Hello','Hi There','zz')";
598
 
599
  $result = $wpdb->query($insert);
600
-
601
  if($result === FALSE)
602
  {
603
-
604
  }
605
  else
606
  {
607
-
608
  add_option(TRANSPOSH_DB_VERSION, DB_VERSION);
609
  }
610
  }
@@ -613,18 +625,18 @@ function setup_db()
613
 
614
  if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name)
615
  {
616
-
617
  $sql = "CREATE TABLE " . $table_name . " (original VARCHAR(256) NOT NULL,
618
  lang CHAR(5) NOT NULL,
619
  translated VARCHAR(256),
620
  translated_by VARCHAR(15),
621
  timestamp TIMESTAMP,
622
  PRIMARY KEY (original, lang, timestamp)) ";
623
-
624
-
625
  dbDelta($sql);
626
  }
627
-
628
 
629
  }
630
 
@@ -644,16 +656,16 @@ function is_translator()
644
 
645
  if(get_option(ANONYMOUS_TRANSLATION))
646
  {
647
- //if anonymous translation is allowed - let anyone enjoy it
648
  return TRUE;
649
  }
650
-
651
  return FALSE;
652
  }
653
-
654
 
655
  /*
656
- * Plugin activated.
657
  *
658
  */
659
  function plugin_activate()
@@ -665,7 +677,7 @@ function plugin_activate()
665
 
666
  add_filter('rewrite_rules_array', 'update_rewrite_rules');
667
  $wp_rewrite->flush_rules();
668
-
669
 
670
  }
671
 
@@ -680,24 +692,24 @@ function plugin_deactivate(){
680
 
681
  remove_filter('rewrite_rules_array', 'update_rewrite_rules');
682
  $wp_rewrite->flush_rules();
683
-
684
 
685
  }
686
 
687
  /*
688
- * Callback from admin_notices - display error message to the admin.
689
  *
690
  */
691
  function plugin_install_error()
692
  {
693
  global $admin_msg;
694
 
695
-
696
  echo '<div class="updated"><p>';
697
  echo 'Error has occured in the installation process of the translation plugin: <br>';
698
-
699
  echo $admin_msg;
700
-
701
  if (function_exists('deactivate_plugins') ) {
702
  deactivate_plugins("transposh/translate.php", "translate.php");
703
  echo '<br> This plugin has been automatically deactivated.';
@@ -710,7 +722,7 @@ function plugin_install_error()
710
  /*
711
  * Callback when all plugins have been loaded. Serves as the location
712
  * to check that the plugin loaded successfully else trigger notification
713
- * to the admin and deactivate plugin.
714
  *
715
  */
716
  function plugin_loaded()
@@ -721,7 +733,7 @@ function plugin_loaded()
721
  if (get_option(TRANSPOSH_DB_VERSION) == NULL)
722
  {
723
  $admin_msg = "Failed to locate the translation table <em> " . TRANSLATIONS_TABLE . "</em> in local database. <br>";
724
-
725
 
726
  //Some error occured - notify admin and deactivate plugin
727
  add_action('admin_notices', 'plugin_install_error');
@@ -732,14 +744,31 @@ function plugin_loaded()
732
  if ($db_version != DB_VERSION)
733
  {
734
  $admin_msg = "Translation database version ($db_version) is not comptabile with this plugin (". DB_VERSION . ") <br>";
735
-
736
 
737
  //Some error occured - notify admin and deactivate plugin
738
  add_action('admin_notices', 'plugin_install_error');
739
  }
740
  }
741
 
742
- //Register callbacks
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
743
  add_action('wp_head', 'add_custom_css');
744
  add_filter('query_vars', 'parameter_queryvars' );
745
 
@@ -747,6 +776,6 @@ add_action('init', 'on_init');
747
  add_action('shutdown', 'on_shutdown');
748
 
749
  add_action( 'plugins_loaded', 'plugin_loaded');
750
- add_action('activate_'.str_replace('\\','/',plugin_basename(__FILE__)),'plugin_activate');
751
- add_action('deactivate_'.str_replace('\\','/',plugin_basename(__FILE__)),'plugin_deactivate');
752
  ?>
4
  Plugin URI: http://transposh.org/#
5
  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>.
6
  Author: Team Transposh
7
+ Version: 0.0.3
8
  Author URI: http://transposh.org/
9
  License: GPL (http://www.gnu.org/licenses/gpl.txt)
10
  */
61
 
62
  //The url pointing to the base of the plugin
63
  $plugin_url;
64
+
65
  //Error message displayed for the admin in case of failure
66
  $admin_msg;
67
 
69
  /*
70
  * Called when the buffer containing the original page is flused. Triggers the
71
  * translation process.
72
+ *
73
+ */
74
  function process_page(&$buffer) {
75
+
76
  global $wp_query, $tr_page, $page, $pos, $lang, $plugin_url, $is_edit_mode, $wpdb,
77
  $table_name;
78
+
79
  $start_time = microtime(TRUE);
80
+
81
  if (!isset($wp_query->query_vars[LANG_PARAM]))
82
  {
83
  //No language code - avoid further processing.
84
  return $buffer;
85
+
86
  }
87
 
88
  $lang = $wp_query->query_vars[LANG_PARAM];
93
 
94
  return $buffer;
95
  }
96
+
97
+
98
  $page = $buffer;
99
 
100
 
104
  //Verify that the current language is editable and that the
105
  //user has the required permissions
106
  $editable_langs = get_option(EDITABLE_LANGS);
107
+
108
  if(is_translator() && strstr($editable_langs, $lang))
109
  {
110
  $is_edit_mode = TRUE;
111
  }
112
+
113
  }
114
+
115
 
116
+
 
117
  //translate the entire page
118
  process_html();
119
+
120
  $end_time = microtime(TRUE);
121
 
122
 
123
+
124
  //return the translated page unless it is empty, othewise return the original
125
  return (strlen($tr_page) > 0 ? $tr_page : $page);
126
  }
127
 
128
  /*
129
  * Fix links on the page. href needs to be modified to include
130
+ * lang specifier and editing mode.
131
  *
132
  */
133
  function process_anchor_tag($start, $end)
134
  {
135
  global $home_url, $home_url_quoted, $lang, $is_edit_mode, $wp_rewrite;
136
+
137
  $href = get_attribute($start, $end, 'href');
138
 
139
  if($href == NULL)
148
  }
149
 
150
  $use_params = FALSE;
151
+
152
+ //Only use params if permalinks are not enabled.
153
  //don't fix links pointing to real files as it will cause that the
154
  //web server will not be able to locate them
155
+ if(!$wp_rewrite->using_permalinks() ||
156
  stripos($href, '/wp-admin') !== FALSE ||
157
  stripos($href, '/wp-content') !== FALSE ||
158
  stripos($href, '/wp-login') !== FALSE ||
170
 
171
 
172
  /*
173
+ * Update the given url to include language params.
174
  * param url - the original url to rewrite
175
  * param lang - language code
176
  * param is_edit - is running in edit mode.
185
  //override the use only params - admin configured system to not touch permalinks
186
  $use_params_only = TRUE;
187
  }
188
+
189
  if($is_edit)
190
  {
191
  $params = EDIT_PARAM . '=1&';
192
+
193
  }
194
 
195
  if($use_params_only)
209
 
210
  //Cleanup extra &
211
  $url = preg_replace("/&&+/", "&", $url);
212
+
213
  //Cleanup extra ?
214
  $url = preg_replace("/\?\?+/", "?", $url);
215
  }
218
  }
219
 
220
  /*
221
+ * Fetch translation from db or cache.
222
  * Returns the translated string or NULL if not available.
223
  */
224
  function fetch_translation($original)
225
  {
226
  global $wpdb, $lang, $table_name;
227
  $translated = NULL;
228
+
229
 
230
  if(ENABLE_APC && function_exists('apc_fetch'))
231
  {
232
  $cached = apc_fetch($original . $lang, $rc);
233
  if($rc === TRUE)
234
  {
235
+
236
+ return $cached;
237
  }
238
  }
239
+
240
+ $query = "SELECT * FROM $table_name WHERE original = '$original' and lang = '$lang' ";
241
  $row = $wpdb->get_row($query);
242
+
243
  if($row !== FALSE)
244
  {
245
  $translated = $row->translated;
246
  $translated = stripslashes($translated);
247
+
248
 
249
  }
250
+
251
+
252
  if(ENABLE_APC && function_exists('apc_store'))
253
  {
254
  //If we don't have translation still we want to have it in cache
257
  {
258
  $cache_entry = "";
259
  }
260
+
261
  //update cache
262
  $rc = apc_store($original . $lang, $cache_entry, 3600);
263
  if($rc === TRUE)
265
 
266
  }
267
  }
268
+
269
 
270
  return $translated;
271
  }
277
  */
278
  function insert_javascript_includes()
279
  {
280
+ global $plugin_url, $wp_query;
281
+
282
+ if (!($wp_query->query_vars[EDIT_PARAM] == "1" ||
283
+ $wp_query->query_vars[EDIT_PARAM] == "true"))
284
+ {
285
+ //check permission later - for now just make sure we don't load the
286
+ //js code when it is not needed
287
+ return;
288
+ }
289
 
290
+
291
  $overlib_dir = "$plugin_url/js/overlibmws";
292
+
293
  $js = "\n<script type=\"text/javascript\" src=\"$overlib_dir/overlibmws.js\"></script>";
294
  $js .= "\n<script type=\"text/javascript\" src=\"$overlib_dir/overlibmws_filter.js\"></script>";
295
  $js .= "\n<script type=\"text/javascript\" src=\"$overlib_dir/overlibmws_modal.js\"></script>";
299
 
300
  $js .= "\n<script type=\"text/javascript\" src=\"$plugin_url/js/transposh.js\"></script>\n";
301
  $js .= "\n<script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js\"></script>\n";
302
+ $js .= "\n<script type=\"text/javascript\" src=\"http://www.google.com/jsapi\"></script>\n";
303
+ $js .= "\n<script type=\"text/javascript\">google.load(\"language\", \"1\");</script>\n";
304
 
305
  echo $js;
306
  }
308
 
309
  /*
310
  * Return the img tag that will added to enable editing a translatable
311
+ * item on the page.
312
  * param segement_id The id (number) identifying this segment. Needs to be
313
  placed within the img tag for use on client side operation (jquery)
314
  */
316
  {
317
  global $plugin_url, $lang, $home_url;
318
  $url = $home_url . '/index.php';
319
+
320
+ //For use in javascript, make the following changes:
321
  //1. Add slashes to escape the inner text
322
  //2. Convert the html special characters
323
  //The browser will take decode step 2 and pass it to the js engine which decode step 1 - a bit tricky
329
  $add_img = "_fix";
330
  }
331
 
332
+ $img = "<img src=\"$plugin_url/translate$add_img.png\" alt=\"translate\" id=\"" . IMG_PREFIX . "$segment_id\"
333
+ onclick=\"translate_dialog('$original','$translation','$lang','$url', '$segment_id'); return false;\"
334
+ onmouseover=\"hint('$original'); return true;\"
335
  onmouseout=\"nd()\" />";
336
+
337
  return $img;
338
  }
339
 
357
  {
358
  return;
359
  }
360
+
361
+ //include the transposh.css
362
  echo "<link rel=\"stylesheet\" href=\"$plugin_url/transposh.css\" type=\"text/css\" />";
363
 
364
 
370
  function init_global_vars()
371
  {
372
  global $home_url, $home_url_quoted, $plugin_url, $table_name, $wpdb;
373
+
374
  $home_url = get_option('home');
375
  $local_dir = preg_replace("/.*\//", "", dirname(__FILE__));
376
+
377
  $plugin_url= $home_url . "/wp-content/plugins/$local_dir";
378
  $home_url_quoted = preg_quote($home_url);
379
  $home_url_quoted = preg_replace("/\//", "\\/", $home_url_quoted);
383
 
384
 
385
  /*
386
+ * A new translation has been posted, update the translation database.
387
  *
388
  */
389
  function update_translation()
390
  {
391
  global $wpdb, $table_name;
392
+
393
  $ref=getenv('HTTP_REFERER');
394
  $original = $_POST['original'];
395
  $translation = $_POST['translation'];
396
  $lang = $_POST['lang'];
397
+
398
  if(!isset($original) || !isset($translation) || !isset($lang))
399
  {
400
  logger("Enter " . __FILE__ . " missing params: $original , $translation, $lang," .
408
 
409
  }
410
 
411
+ //Decode & remove already escaped character to avoid double escaping
412
  $original = $wpdb->escape(stripslashes(urldecode($original)));
413
  $translation = $wpdb->escape(htmlspecialchars(stripslashes(urldecode($translation))));
414
+
415
  $update = "REPLACE INTO $table_name (original, translated, lang)
416
  VALUES ('" . $original . "','" . $translation . "','" . $lang . "')";
417
 
466
  {
467
 
468
  }
469
+
470
  }
471
 
472
 
478
  function get_default_lang()
479
  {
480
  global $languages;
481
+
482
  $default = get_option(DEFAULT_LANG);
483
  if(!$languages[$default])
484
  {
511
 
512
 
513
  /*
514
+ * Page generation completed - flush buffer.
515
  */
516
  function on_shutdown()
517
  {
531
 
532
  return $rule;
533
  }
534
+
535
  $newRules = array();
536
  $lang_prefix="([a-z]{2,2}(\-[a-z]{2,2})?)/";
537
 
538
  $lang_parameter= "&" . LANG_PARAM . '=$matches[1]';
539
 
540
+ //catch the root url
541
  $newRules[$lang_prefix."?$"] = "index.php?lang=\$matches[1]";
542
 
543
 
544
  foreach ($rules as $key=>$value) {
545
  $original_key = $key;
546
  $original_value = $value;
547
+
548
  $key = $lang_prefix . $key;
549
 
550
  //Shift existing matches[i] two step forward as we pushed new elements
555
  }
556
 
557
  $value .= $lang_parameter;
558
+
559
 
560
+
 
561
 
562
  $newRules[$key] = $value;
563
  $newRules[$original_key] = $original_value;
582
 
583
 
584
  /*
585
+ * Setup the translation database.
586
  *
587
  */
588
+ function setup_db()
589
  {
590
 
591
  global $wpdb;
595
 
596
  if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name)
597
  {
598
+
599
  $sql = "CREATE TABLE " . $table_name . " (original VARCHAR(256) NOT NULL,
600
  lang CHAR(5) NOT NULL,
601
  translated VARCHAR(256),
602
  PRIMARY KEY (original, lang)) ";
603
+
604
+
605
  dbDelta($sql);
606
 
607
  //Verify that newly created table is ready for use.
609
  "VALUES ('Hello','Hi There','zz')";
610
 
611
  $result = $wpdb->query($insert);
612
+
613
  if($result === FALSE)
614
  {
615
+
616
  }
617
  else
618
  {
619
+
620
  add_option(TRANSPOSH_DB_VERSION, DB_VERSION);
621
  }
622
  }
625
 
626
  if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name)
627
  {
628
+
629
  $sql = "CREATE TABLE " . $table_name . " (original VARCHAR(256) NOT NULL,
630
  lang CHAR(5) NOT NULL,
631
  translated VARCHAR(256),
632
  translated_by VARCHAR(15),
633
  timestamp TIMESTAMP,
634
  PRIMARY KEY (original, lang, timestamp)) ";
635
+
636
+
637
  dbDelta($sql);
638
  }
639
+
640
 
641
  }
642
 
656
 
657
  if(get_option(ANONYMOUS_TRANSLATION))
658
  {
659
+ //if anonymous translation is allowed - let anyone enjoy it
660
  return TRUE;
661
  }
662
+
663
  return FALSE;
664
  }
665
+
666
 
667
  /*
668
+ * Plugin activated.
669
  *
670
  */
671
  function plugin_activate()
677
 
678
  add_filter('rewrite_rules_array', 'update_rewrite_rules');
679
  $wp_rewrite->flush_rules();
680
+
681
 
682
  }
683
 
692
 
693
  remove_filter('rewrite_rules_array', 'update_rewrite_rules');
694
  $wp_rewrite->flush_rules();
695
+
696
 
697
  }
698
 
699
  /*
700
+ * Callback from admin_notices - display error message to the admin.
701
  *
702
  */
703
  function plugin_install_error()
704
  {
705
  global $admin_msg;
706
 
707
+
708
  echo '<div class="updated"><p>';
709
  echo 'Error has occured in the installation process of the translation plugin: <br>';
710
+
711
  echo $admin_msg;
712
+
713
  if (function_exists('deactivate_plugins') ) {
714
  deactivate_plugins("transposh/translate.php", "translate.php");
715
  echo '<br> This plugin has been automatically deactivated.';
722
  /*
723
  * Callback when all plugins have been loaded. Serves as the location
724
  * to check that the plugin loaded successfully else trigger notification
725
+ * to the admin and deactivate plugin.
726
  *
727
  */
728
  function plugin_loaded()
733
  if (get_option(TRANSPOSH_DB_VERSION) == NULL)
734
  {
735
  $admin_msg = "Failed to locate the translation table <em> " . TRANSLATIONS_TABLE . "</em> in local database. <br>";
736
+
737
 
738
  //Some error occured - notify admin and deactivate plugin
739
  add_action('admin_notices', 'plugin_install_error');
744
  if ($db_version != DB_VERSION)
745
  {
746
  $admin_msg = "Translation database version ($db_version) is not comptabile with this plugin (". DB_VERSION . ") <br>";
747
+
748
 
749
  //Some error occured - notify admin and deactivate plugin
750
  add_action('admin_notices', 'plugin_install_error');
751
  }
752
  }
753
 
754
+ /*
755
+ * Gets the plugin name to be used in activation/decativation hooks.
756
+ * Keep only the file name and its containing directory. Don't use the full
757
+ * path as it will break when using symbollic links.
758
+ */
759
+ function get_plugin_name()
760
+ {
761
+ $file = __FILE__;
762
+ $file = str_replace('\\','/',$file); // sanitize for Win32 installs
763
+ $file = preg_replace('|/+|','/', $file); // remove any duplicate slash
764
+
765
+ //keep only the file name and its parent directory
766
+ $file = preg_replace('/.*(\/[^\/]+\/[^\/]+)$/', '$1', $file);
767
+
768
+ return $file;
769
+ }
770
+
771
+ //Register callbacks
772
  add_action('wp_head', 'add_custom_css');
773
  add_filter('query_vars', 'parameter_queryvars' );
774
 
776
  add_action('shutdown', 'on_shutdown');
777
 
778
  add_action( 'plugins_loaded', 'plugin_loaded');
779
+ register_activation_hook(get_plugin_name(), 'plugin_activate');
780
+ register_deactivation_hook(get_plugin_name(),'plugin_deactivate');
781
  ?>
transposh_widget.php CHANGED
@@ -101,13 +101,12 @@ function transposh_widget($args)
101
  $is_showing_languages = FALSE;
102
 
103
  echo $before_widget . $before_title . __(no_translate("Transposh")) . $after_title;
104
- echo "<span class=\"" . NO_TRANSLATE_CLASS . "\" >";
105
-
106
  switch ($options['style']) {
107
  case 1: // flags
108
  //keep the flags in the same direction regardless of the overall page direction
109
- echo "<div dir=rtl>";
110
-
111
  global $plugin_url;
112
  $using_permalinks = $wp_rewrite->using_permalinks();
113
 
@@ -130,7 +129,6 @@ function transposh_widget($args)
130
  $is_showing_languages = TRUE;
131
  }
132
  }
133
-
134
  echo "</div>";
135
 
136
  // this is the form for the edit...
@@ -140,6 +138,7 @@ function transposh_widget($args)
140
  default: // language list
141
 
142
  echo "<form action=\"$page_url\" method=\"post\">";
 
143
  echo "<select name=\"lang\" id=\"lang\" onchange=\"Javascript:this.form.submit();\">";
144
  echo "<option value=\"none\">[Language]</option>";
145
 
@@ -152,11 +151,12 @@ function transposh_widget($args)
152
  ($is_translator && strstr($editable_langs, $code)))
153
  {
154
  $is_selected = ($lang == $code ? "selected=\"selected\"" : "" );
155
- echo "<option value=\"$code\" $is_selected>" . no_translate($language) . "</option>";
156
  $is_showing_languages = TRUE;
157
  }
158
  }
159
  echo "</select><br/>";
 
160
  }
161
 
162
 
@@ -168,7 +168,7 @@ function transposh_widget($args)
168
  {
169
  echo "<input type=\"checkbox\" name=\"" . EDIT_PARAM . "\" value=\"1\"" .
170
  ($is_edit ? "checked=\"1\"" : "0") .
171
- "\" onClick=\"this.form.submit();\"/>Edit Translation<br/>";
172
  }
173
 
174
  echo "<input type=\"hidden\" name=\"transposh_widget_posted\" value=\"1\"/>";
@@ -180,7 +180,6 @@ function transposh_widget($args)
180
  }
181
 
182
  echo "</form>";
183
- echo "</span>"; // the no_translate for the widget
184
 
185
  echo $after_widget;
186
  }
101
  $is_showing_languages = FALSE;
102
 
103
  echo $before_widget . $before_title . __(no_translate("Transposh")) . $after_title;
104
+
 
105
  switch ($options['style']) {
106
  case 1: // flags
107
  //keep the flags in the same direction regardless of the overall page direction
108
+ echo "<div style=\"text-align: left;\" class=\"" . NO_TRANSLATE_CLASS . "\" >";
109
+
110
  global $plugin_url;
111
  $using_permalinks = $wp_rewrite->using_permalinks();
112
 
129
  $is_showing_languages = TRUE;
130
  }
131
  }
 
132
  echo "</div>";
133
 
134
  // this is the form for the edit...
138
  default: // language list
139
 
140
  echo "<form action=\"$page_url\" method=\"post\">";
141
+ echo "<span class=\"" . NO_TRANSLATE_CLASS . "\" >";
142
  echo "<select name=\"lang\" id=\"lang\" onchange=\"Javascript:this.form.submit();\">";
143
  echo "<option value=\"none\">[Language]</option>";
144
 
151
  ($is_translator && strstr($editable_langs, $code)))
152
  {
153
  $is_selected = ($lang == $code ? "selected=\"selected\"" : "" );
154
+ echo "<option value=\"$code\" $is_selected>" . $language . "</option>";
155
  $is_showing_languages = TRUE;
156
  }
157
  }
158
  echo "</select><br/>";
159
+ echo "</span>"; // the no_translate for the language list
160
  }
161
 
162
 
168
  {
169
  echo "<input type=\"checkbox\" name=\"" . EDIT_PARAM . "\" value=\"1\"" .
170
  ($is_edit ? "checked=\"1\"" : "0") .
171
+ "\" onClick=\"this.form.submit();\"/>&nbsp;Edit Translation";
172
  }
173
 
174
  echo "<input type=\"hidden\" name=\"transposh_widget_posted\" value=\"1\"/>";
180
  }
181
 
182
  echo "</form>";
 
183
 
184
  echo $after_widget;
185
  }