Transposh WordPress Translation - Version 0.2.4

Version Description

Download this release

Release Info

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

Code changes from version 0.2.3 to 0.2.4

Files changed (9) hide show
  1. core/constants.php +48 -44
  2. core/globals.php +2 -2
  3. core/parser.php +145 -42
  4. core/utils.php +42 -46
  5. readme.txt +11 -2
  6. transposh.php +265 -289
  7. transposh_admin.php +82 -81
  8. transposh_db.php +226 -242
  9. transposh_widget.php +138 -162
core/constants.php CHANGED
@@ -30,55 +30,56 @@ define("NO_TRANSLATE_CLASS", "no_translate");
30
 
31
  //Supported languages, new languages can be added here
32
  //the array directs from language code to - Native name, flag, auto-translatable
33
- $languages = array("en" => "English,us,1",
34
- "sq" => "Shqip,al,1",
35
- "ar" => "العربية,sa,1",
36
- "bg" => "Български,bg,1",
37
- "ca" => "Català,catalonia,1",
38
- "zh" => "中文(简体),cn,1",
39
- "zh-tw" => "中文(漢字),tw,1",
40
- "hr" => "Hrvatski,hr,1",
41
- "cs" => "čeština,cz,1",
42
- "da" => "dansk,dk,1",
43
- "nl" => "Nederlands,nl,1",
44
- "et" => "Eesti keel,ee,1",
45
- "fi" => "Suomi,fi,1",
46
- "fr" => "Français,fr,1",
47
- "gl" => "Galego,galicia,1",
48
- "de" => "Deutsch,de,1",
49
- "el" => "Ελληνικά,gr,1",
50
- "he" => "עברית,il,1",
51
- "hi" => "हिन्दी; हिंदी,in,1",
52
- "hu" => "magyar,hu,1",
53
- "id" => "Bahasa Indonesia,id,1",
54
- "it" => "Italiano,it,1",
55
- "is" => "íslenska,is,0",
56
- "ja" => "日本語,jp,1",
57
- "ko" => "우리말,kr,1",
58
- "lv" => "latviešu valoda,lv,1",
59
- "lt" => "lietuvių kalba,lt,1",
60
- "mt" => "Malti,mt,1",
61
- "no" => "Norsk,no,1",
62
- "pl" => "Polski,pl,1",
63
- "pt" => "Português,pt,1",
64
- "ro" => "Română,ro,1",
65
- "ru" => "Русский,ru,1",
66
- "sr" => "српски језик,rs,1",
67
- "sk" => "slovenčina,sk,1",
68
- "sl" => "slovenščina,sl,1",
69
- "es" => "Español,es,1",
70
- "sv" => "svenska,se,1",
71
- "tl" => "Tagalog,ph,1",
72
- "th" => "ภาษาไทย,th,1",
73
- "tr" => "Türkçe,tr,1",
74
- "uk" => "Українська,ua,1",
75
- "vi" => "Tiếng Việt,vn,1");
 
76
 
77
  //Language which are read from right to left (rtl)
78
  $rtl_languages = array("ar", "he");
79
 
80
  //Define the new capability that will be assigned to roles - translator
81
- define("TRANLSLATOR", 'translator');
82
 
83
  //Option defining whether anonymous translation is allowed.
84
  define("ANONYMOUS_TRANSLATION", "transposh_allow_anonymous_translation");
@@ -98,6 +99,9 @@ define("ENABLE_PERMALINKS_REWRITE", "transposh_enable_permalinks");
98
  //Option to enable/disable default language translation
99
  define("ENABLE_DEFAULT_TRANSLATE", "transposh_enable_default_translate");
100
 
 
 
 
101
  //Option defining the default language
102
  define("DEFAULT_LANG", "transposh_default_language");
103
 
30
 
31
  //Supported languages, new languages can be added here
32
  //the array directs from language code to - Native name, flag, auto-translatable
33
+ $languages = array(
34
+ "en" => "English,us,1",
35
+ "sq" => "Shqip,al,1",
36
+ "ar" => "العربية,sa,1",
37
+ "bg" => "Български,bg,1",
38
+ "ca" => "Català,catalonia,1",
39
+ "zh" => "中文(简体),cn,1",
40
+ "zh-tw" => "中文(漢字),tw,1",
41
+ "hr" => "Hrvatski,hr,1",
42
+ "cs" => "čeština,cz,1",
43
+ "da" => "dansk,dk,1",
44
+ "nl" => "Nederlands,nl,1",
45
+ "et" => "Eesti keel,ee,1",
46
+ "fi" => "Suomi,fi,1",
47
+ "fr" => "Français,fr,1",
48
+ "gl" => "Galego,galicia,1",
49
+ "de" => "Deutsch,de,1",
50
+ "el" => "Ελληνικά,gr,1",
51
+ "he" => "עברית,il,1",
52
+ "hi" => "हिन्दी; हिंदी,in,1",
53
+ "hu" => "magyar,hu,1",
54
+ "id" => "Bahasa Indonesia,id,1",
55
+ "it" => "Italiano,it,1",
56
+ "is" => "íslenska,is,0",
57
+ "ja" => "日本語,jp,1",
58
+ "ko" => "우리말,kr,1",
59
+ "lv" => "latviešu valoda,lv,1",
60
+ "lt" => "lietuvių kalba,lt,1",
61
+ "mt" => "Malti,mt,1",
62
+ "no" => "Norsk,no,1",
63
+ "pl" => "Polski,pl,1",
64
+ "pt" => "Português,pt,1",
65
+ "ro" => "Română,ro,1",
66
+ "ru" => "Русский,ru,1",
67
+ "sr" => "српски језик,rs,1",
68
+ "sk" => "slovenčina,sk,1",
69
+ "sl" => "slovenščina,sl,1",
70
+ "es" => "Español,es,1",
71
+ "sv" => "svenska,se,1",
72
+ "tl" => "Tagalog,ph,1",
73
+ "th" => "ภาษาไทย,th,1",
74
+ "tr" => "Türkçe,tr,1",
75
+ "uk" => "Українська,ua,1",
76
+ "vi" => "Tiếng Việt,vn,1");
77
 
78
  //Language which are read from right to left (rtl)
79
  $rtl_languages = array("ar", "he");
80
 
81
  //Define the new capability that will be assigned to roles - translator
82
+ define("TRANSLATOR", 'translator');
83
 
84
  //Option defining whether anonymous translation is allowed.
85
  define("ANONYMOUS_TRANSLATION", "transposh_allow_anonymous_translation");
99
  //Option to enable/disable default language translation
100
  define("ENABLE_DEFAULT_TRANSLATE", "transposh_enable_default_translate");
101
 
102
+ //Option to enable/disable footer scripts (2.8 and up)
103
+ define("ENABLE_FOOTER_SCRIPTS", "transposh_enable_footer_scripts");
104
+
105
  //Option defining the default language
106
  define("DEFAULT_LANG", "transposh_default_language");
107
 
core/globals.php CHANGED
@@ -18,10 +18,10 @@
18
 
19
 
20
  /**
21
- *
22
  * Contains the global settings which are shared among the different tasks
23
  * of this plugin.
24
- *
25
  */
26
 
27
  //Home (root) url of the site/blog under which translation will take place.
18
 
19
 
20
  /**
21
+ *
22
  * Contains the global settings which are shared among the different tasks
23
  * of this plugin.
24
+ *
25
  */
26
 
27
  //Home (root) url of the site/blog under which translation will take place.
core/parser.php CHANGED
@@ -33,6 +33,7 @@ class parser {
33
  private $inbody = false;
34
  public $is_edit_mode;
35
  public $is_auto_translate;
 
36
  protected $ignore_tags = array('script'=>1, 'style'=>1, 'code'=>1);
37
 
38
  /**
@@ -40,8 +41,7 @@ class parser {
40
  * @param $char
41
  * @return bool true if current position marks a white space
42
  */
43
- function is_white_space($char)
44
- {
45
  if (!$char) return TRUE;
46
  return strspn($char, " \t\r\n\0\x0B");
47
  }
@@ -51,8 +51,7 @@ class parser {
51
  * range of a-z (case insensetive).
52
  * @return bool true if a-z
53
  */
54
- function is_a_to_z_character($char)
55
- {
56
  return (($char >= 'a' && $char <= 'z') || ($char >= 'A' && $char <= 'Z')) ? true : false;
57
  }
58
 
@@ -60,8 +59,7 @@ class parser {
60
  * Determine if the current position is a digit.
61
  * @return bool true if a digit
62
  */
63
- function is_digit($char)
64
- {
65
  return (($char >= '0' && $char <= '9')) ? true : false;
66
  }
67
 
@@ -71,10 +69,8 @@ class parser {
71
  * @param $position where to check for entities
72
  * @return int length of entity
73
  */
74
- function is_html_entity($string, $position)
75
- {
76
- if ($string[$position] == "&")
77
- {
78
  $end_pos = $position + 1;
79
  while($string[$end_pos] == "#" || $this->is_digit($string[$end_pos]) || $this->is_a_to_z_character($string[$end_pos])) ++$end_pos;
80
  if ($string[$end_pos] == ';') return $end_pos - $position +1;
@@ -90,7 +86,87 @@ class parser {
90
  * @return - true if not a breaker (apostrophy)
91
  */
92
  function is_entity_breaker($entity) {
93
- return !(strpos('&#8217;&apos;&#039;&#39;', $entity) !== FALSE);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
95
 
96
  /**
@@ -100,8 +176,7 @@ class parser {
100
  * @param $nextchar needed for checking if . or - breaks
101
  * @return int length of breaker if current position marks a break in sentence
102
  */
103
- function is_sentence_breaker($char, $nextchar, $nextnextchar)
104
- {
105
  if (($char == '.' || $char == '-') && ($this->is_white_space($nextchar))) return 1;
106
  if (ord($char) == 226 && ord($nextchar) == 136 && ord($nextnextchar) == 153) return 3; //∙
107
  if (ord($char) == 194 && ord($nextchar) == 183) return 2; //·
@@ -112,8 +187,7 @@ class parser {
112
  * Determines if the current position marks the begining of a number, e.g. 123 050-391212232
113
  * @return length of number.
114
  */
115
- function is_number($page, $position)
116
- {
117
  return strspn($page,'0123456789-+,.\\/',$position);
118
  }
119
 
@@ -132,7 +206,7 @@ class parser {
132
  $node->_[HDOM_INFO_OUTER] = '';
133
  $node->phrase = $phrase;
134
  if ($this->inbody)
135
- $node->inbody = $this->inbody;
136
  }
137
  }
138
 
@@ -145,13 +219,12 @@ class parser {
145
  // $pos = skip_white_space($string, $pos);
146
  $start = $pos;
147
 
148
- while($pos < strlen($string))
149
- {
150
- // Some HTML entities make us break, almost all but apostrophies
151
- if($len_of_entity = $this->is_html_entity($string,$pos))
152
- {
153
- if($this->is_white_space($string[$pos+$len_of_entity]) || $this->is_entity_breaker(substr($string,$pos,$len_of_entity)))
154
- {
155
  $this->tag_phrase($string,$start,$pos);
156
  $start = $pos + $len_of_entity;
157
  }
@@ -159,30 +232,26 @@ class parser {
159
  $pos += $len_of_entity;
160
  }
161
  // will break translation unit when there's a breaker ",.[]()..."
162
- else if($senb_len = $this->is_sentence_breaker($string[$pos],$string[$pos+1],$string[$pos+2]))
163
- {
164
  $this->tag_phrase($string,$start,$pos);
165
  $pos += $senb_len;
166
  $start = $pos;
167
  }
168
  // Numbers also break, if they are followed by whitespace (don't break 42nd)
169
- else if($num_len = $this->is_number($string,$pos))
170
- {
171
  if ($this->is_white_space($string[$pos+$num_len])) {
172
  $this->tag_phrase($string,$start,$pos);
173
  $start = $pos + $num_len + 1;
174
  }
175
  $pos += $num_len + 1;
176
  }
177
- else
178
- {
179
  $pos++;
180
  }
181
  }
182
 
183
  // the end is also some breaker
184
- if($pos > $start)
185
- {
186
  $this->tag_phrase($string,$start,$pos);
187
  }
188
  }
@@ -198,7 +267,7 @@ class parser {
198
  if (stripos($node->class,NO_TRANSLATE_CLASS) !== false) return;
199
  if (isset($this->ignore_tags[$node->tag])) return;
200
  elseif ($node->tag == 'text') {
201
- // this prevents translation of a link that just surrounds its address
202
  if ($node->parent->tag == 'a' && $node->parent->href == $node->outertext) {
203
  return;
204
  }
@@ -226,6 +295,9 @@ class parser {
226
  // titles are also good places to translate, exist in a, img, abbr, acronym
227
  if ($node->title) $this->parsetext($node->title);
228
 
 
 
 
229
  // recurse
230
  foreach($node->nodes as $c) {
231
  $this->translate_tagging($c);
@@ -241,8 +313,8 @@ class parser {
241
  * @return string
242
  */
243
  function create_edit_span ($original_text , $translated_text, $source, $for_hidden_element = false) {
244
- // Use base64 encoding to make that when the page is translated (i.e. update_translation) we
245
- // get back exactlly the same string without having the client decode/encode it in anyway.
246
  $span = '<span class ="'.SPAN_PREFIX.'" id="'.SPAN_PREFIX.$this->segment_id.'" token="' . base64_url_encode($original_text)."\" source=\"$source\"";
247
  // those are needed for on the fly image creation / hidden elements translations
248
  if ($this->is_edit_mode || $for_hidden_element) {
@@ -266,17 +338,17 @@ class parser {
266
  * @return string Translated content is here
267
  */
268
  function fix_html($string) {
269
- // create our dom
270
  $this->html = str_get_html($string);
271
  // mark translateable elements
272
  $this->translate_tagging($this->html->root);
273
 
274
  // first fix the html tag itself - we might need to to the same for all such attributes with flipping
275
  if ($this->dir_rtl)
276
- $this->html->find('html',0)->dir="rtl";
277
 
278
  if ($this->lang)
279
- $this->html->find('html',0)->lang=$lang;
280
 
281
  // not much point in further processing if we don't have a function that does it
282
  if ($this->fetch_translate_func == null) {
@@ -305,7 +377,13 @@ class parser {
305
  }
306
  }
307
  if ($newtext) {
 
 
 
 
 
308
  $e->outertext = $newtext.$right;
 
309
  }
310
  }
311
 
@@ -325,9 +403,9 @@ class parser {
325
  if ($ep->tag == 'phrase') {
326
  list ($translated_text, $source) = call_user_func_array($this->fetch_translate_func,array($ep->phrase, $this->lang));
327
  if (($this->is_edit_mode || ($this->is_auto_translate && $translated_text == null)) && $ep->inbody) {
328
- // prevent duplicate translation (title = text)
329
  if (strpos($e->innertext,base64_url_encode($ep->phrase)) === false) {
330
- //no need to translate span the same hidden phrase more than once
331
  if (!in_array($ep->phrase, $hidden_phrases)) {
332
  $span .= $this->create_edit_span($ep->phrase, $translated_text, $source, true)."</span>";
333
  //
@@ -342,9 +420,11 @@ class parser {
342
  }
343
  }
344
  }
345
- if ($newtext)
346
- $e->title = $newtext.$right;
347
-
 
 
348
  $e->outertext .= $span;
349
  // this is where we update in the outercase issue
350
  if ($e->parent->_[HDOM_INFO_OUTER]) {
@@ -353,6 +433,29 @@ class parser {
353
 
354
  }
355
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  return $this->html;
357
  }
358
  }
33
  private $inbody = false;
34
  public $is_edit_mode;
35
  public $is_auto_translate;
36
+ public $feed_fix;
37
  protected $ignore_tags = array('script'=>1, 'style'=>1, 'code'=>1);
38
 
39
  /**
41
  * @param $char
42
  * @return bool true if current position marks a white space
43
  */
44
+ function is_white_space($char) {
 
45
  if (!$char) return TRUE;
46
  return strspn($char, " \t\r\n\0\x0B");
47
  }
51
  * range of a-z (case insensetive).
52
  * @return bool true if a-z
53
  */
54
+ function is_a_to_z_character($char) {
 
55
  return (($char >= 'a' && $char <= 'z') || ($char >= 'A' && $char <= 'Z')) ? true : false;
56
  }
57
 
59
  * Determine if the current position is a digit.
60
  * @return bool true if a digit
61
  */
62
+ function is_digit($char) {
 
63
  return (($char >= '0' && $char <= '9')) ? true : false;
64
  }
65
 
69
  * @param $position where to check for entities
70
  * @return int length of entity
71
  */
72
+ function is_html_entity($string, $position) {
73
+ if ($string[$position] == "&") {
 
 
74
  $end_pos = $position + 1;
75
  while($string[$end_pos] == "#" || $this->is_digit($string[$end_pos]) || $this->is_a_to_z_character($string[$end_pos])) ++$end_pos;
76
  if ($string[$end_pos] == ';') return $end_pos - $position +1;
86
  * @return - true if not a breaker (apostrophy)
87
  */
88
  function is_entity_breaker($entity) {
89
+ return !(stripos('&#8217;&apos;&#039;&#39;', $entity) !== FALSE);
90
+ }
91
+
92
+ /**
93
+ * Some entities are to be regarded as simple letters in most cases
94
+ &Agrave; &#192; À À latin capital letter A with grave
95
+ &Aacute; &#193; Á Á latin capital letter A with acute
96
+ &Acirc; &#194; Â Â latin capital letter A with circumflex
97
+ &Atilde; &#195; Ã Ã latin capital letter A with tilde
98
+ &Auml; &#196; Ä Ä latin capital letter A with diaeresis
99
+ &Aring; &#197; Å Å latin capital letter A with ring above
100
+ &AElig; &#198; Æ Æ latin capital letter AE
101
+ &Ccedil; &#199; Ç Ç latin capital letter C with cedilla
102
+ &Egrave; &#200; È È latin capital letter E with grave
103
+ &Eacute; &#201; É É latin capital letter E with acute
104
+ &Ecirc; &#202; Ê Ê latin capital letter E with circumflex
105
+ &Euml; &#203; Ë Ë latin capital letter E with diaeresis
106
+ &Igrave; &#204; Ì Ì latin capital letter I with grave
107
+ &Iacute; &#205; Í Í latin capital letter I with acute
108
+ &Icirc; &#206; Î Î latin capital letter I with circumflex
109
+ &Iuml; &#207; Ï Ï latin capital letter I with diaeresis
110
+ &ETH; &#208; Ð Ð latin capital letter ETH
111
+ &Ntilde; &#209; Ñ Ñ latin capital letter N with tilde
112
+ &Ograve; &#210; Ò Ò latin capital letter O with grave
113
+ &Oacute; &#211; Ó Ó latin capital letter O with acute
114
+ &Ocirc; &#212; Ô Ô latin capital letter O with circumflex
115
+ &Otilde; &#213; Õ Õ latin capital letter O with tilde
116
+ &Ouml; &#214; Ö Ö latin capital letter O with diaeresis
117
+ //&times; &#215; × × multiplication sign
118
+ &Oslash; &#216; Ø Ø latin capital letter O with stroke
119
+ &Ugrave; &#217; Ù Ù latin capital letter U with grave
120
+ &Uacute; &#218; Ú Ú latin capital letter U with acute
121
+ &Ucirc; &#219; Û Û latin capital letter U with circumflex
122
+ &Uuml; &#220; Ü Ü latin capital letter U with diaeresis
123
+ &Yacute; &#221; Ý Ý latin capital letter Y with acute
124
+ &THORN; &#222; Þ Þ latin capital letter THORN
125
+ &szlig; &#223; ß ß latin small letter sharp s
126
+ &agrave; &#224; à à latin small letter a with grave
127
+ &aacute; &#225; á á latin small letter a with acute
128
+ &acirc; &#226; â â latin small letter a with circumflex
129
+ &atilde; &#227; ã ã latin small letter a with tilde
130
+ &auml; &#228; ä ä latin small letter a with diaeresis
131
+ &aring; &#229; å å latin small letter a with ring above
132
+ &aelig; &#230; æ æ latin small letter ae
133
+ &ccedil; &#231; ç ç latin small letter c with cedilla
134
+ &egrave; &#232; è è latin small letter e with grave
135
+ &eacute; &#233; é é latin small letter e with acute
136
+ &ecirc; &#234; ê ê latin small letter e with circumflex
137
+ &euml; &#235; ë ë latin small letter e with diaeresis
138
+ &igrave; &#236; ì ì latin small letter i with grave
139
+ &iacute; &#237; í í latin small letter i with acute
140
+ &icirc; &#238; î î latin small letter i with circumflex
141
+ &iuml; &#239; ï ï latin small letter i with diaeresis
142
+ &eth; &#240; ð ð latin small letter eth
143
+ &ntilde; &#241; ñ ñ latin small letter n with tilde
144
+ &ograve; &#242; ò ò latin small letter o with grave
145
+ &oacute; &#243; ó ó latin small letter o with acute
146
+ &ocirc; &#244; ô ô latin small letter o with circumflex
147
+ &otilde; &#245; õ õ latin small letter o with tilde
148
+ &ouml; &#246; ö ö latin small letter o with diaeresis
149
+ //&divide; &#247; ÷ ÷ division sign
150
+ &oslash; &#248; ø ø latin small letter o with stroke
151
+ &ugrave; &#249; ù ù latin small letter u with grave
152
+ &uacute; &#250; ú ú latin small letter u with acute
153
+ &ucirc; &#251; û û latin small letter u with circumflex
154
+ &uuml; &#252; ü ü latin small letter u with diaeresis
155
+ &yacute; &#253; ý ý latin small letter y with acute
156
+ &thorn; &#254; þ þ latin small letter thorn
157
+ &yuml; &#255; ÿ ÿ latin small letter y with diaeresis
158
+ */
159
+
160
+ function is_entity_letter($entity) {
161
+
162
+ $entnum = (int)substr($entity,2);
163
+ if (($entnum >= 192 && $entnum <= 214) || ($entnum >= 216 && $entnum <= 246) || ($entnum >= 248 && $entnum <= 255)) {
164
+ return true;
165
+ }
166
+ $entities = '&Agrave;&Aacute;&Acirc;&Atilde;&Auml;&Aring;&AElig;&Ccedil;&Egrave;&Eacute;&Ecirc;&Euml;&Igrave;&Iacute;&Icirc;&Iuml;&ETH;'.
167
+ '&Ntilde;&Ograve;&Oacute;&Ocirc;&Otilde;&Ouml;&Oslash;&Ugrave;&Uacute;&Ucirc;&Uuml;&Yacute;&THORN;&szlig;'.
168
+ '&oslash;&ugrave;&yuml;';
169
+ return (stripos($entities, $entity) !== FALSE);
170
  }
171
 
172
  /**
176
  * @param $nextchar needed for checking if . or - breaks
177
  * @return int length of breaker if current position marks a break in sentence
178
  */
179
+ function is_sentence_breaker($char, $nextchar, $nextnextchar) {
 
180
  if (($char == '.' || $char == '-') && ($this->is_white_space($nextchar))) return 1;
181
  if (ord($char) == 226 && ord($nextchar) == 136 && ord($nextnextchar) == 153) return 3; //∙
182
  if (ord($char) == 194 && ord($nextchar) == 183) return 2; //·
187
  * Determines if the current position marks the begining of a number, e.g. 123 050-391212232
188
  * @return length of number.
189
  */
190
+ function is_number($page, $position) {
 
191
  return strspn($page,'0123456789-+,.\\/',$position);
192
  }
193
 
206
  $node->_[HDOM_INFO_OUTER] = '';
207
  $node->phrase = $phrase;
208
  if ($this->inbody)
209
+ $node->inbody = $this->inbody;
210
  }
211
  }
212
 
219
  // $pos = skip_white_space($string, $pos);
220
  $start = $pos;
221
 
222
+ while($pos < strlen($string)) {
223
+ // Some HTML entities make us break, almost all but apostrophies
224
+ if($len_of_entity = $this->is_html_entity($string,$pos)) {
225
+ $entity = substr($string,$pos,$len_of_entity);
226
+ if(($this->is_white_space($string[$pos+$len_of_entity]) || $this->is_entity_breaker($entity)) && !$this->is_entity_letter($entity)) {
227
+
 
228
  $this->tag_phrase($string,$start,$pos);
229
  $start = $pos + $len_of_entity;
230
  }
232
  $pos += $len_of_entity;
233
  }
234
  // will break translation unit when there's a breaker ",.[]()..."
235
+ elseif($senb_len = $this->is_sentence_breaker($string[$pos],$string[$pos+1],$string[$pos+2])) {
 
236
  $this->tag_phrase($string,$start,$pos);
237
  $pos += $senb_len;
238
  $start = $pos;
239
  }
240
  // Numbers also break, if they are followed by whitespace (don't break 42nd)
241
+ elseif($num_len = $this->is_number($string,$pos)) {
 
242
  if ($this->is_white_space($string[$pos+$num_len])) {
243
  $this->tag_phrase($string,$start,$pos);
244
  $start = $pos + $num_len + 1;
245
  }
246
  $pos += $num_len + 1;
247
  }
248
+ else {
 
249
  $pos++;
250
  }
251
  }
252
 
253
  // the end is also some breaker
254
+ if($pos > $start) {
 
255
  $this->tag_phrase($string,$start,$pos);
256
  }
257
  }
267
  if (stripos($node->class,NO_TRANSLATE_CLASS) !== false) return;
268
  if (isset($this->ignore_tags[$node->tag])) return;
269
  elseif ($node->tag == 'text') {
270
+ // this prevents translation of a link that just surrounds its address
271
  if ($node->parent->tag == 'a' && $node->parent->href == $node->outertext) {
272
  return;
273
  }
295
  // titles are also good places to translate, exist in a, img, abbr, acronym
296
  if ($node->title) $this->parsetext($node->title);
297
 
298
+ // Meta content (keywords, description) are also good places to translate
299
+ if ($node->tag == 'meta' && $node->content) $this->parsetext($node->content);
300
+
301
  // recurse
302
  foreach($node->nodes as $c) {
303
  $this->translate_tagging($c);
313
  * @return string
314
  */
315
  function create_edit_span ($original_text , $translated_text, $source, $for_hidden_element = false) {
316
+ // Use base64 encoding to make that when the page is translated (i.e. update_translation) we
317
+ // get back exactlly the same string without having the client decode/encode it in anyway.
318
  $span = '<span class ="'.SPAN_PREFIX.'" id="'.SPAN_PREFIX.$this->segment_id.'" token="' . base64_url_encode($original_text)."\" source=\"$source\"";
319
  // those are needed for on the fly image creation / hidden elements translations
320
  if ($this->is_edit_mode || $for_hidden_element) {
338
  * @return string Translated content is here
339
  */
340
  function fix_html($string) {
341
+ // create our dom
342
  $this->html = str_get_html($string);
343
  // mark translateable elements
344
  $this->translate_tagging($this->html->root);
345
 
346
  // first fix the html tag itself - we might need to to the same for all such attributes with flipping
347
  if ($this->dir_rtl)
348
+ $this->html->find('html',0)->dir="rtl";
349
 
350
  if ($this->lang)
351
+ $this->html->find('html',0)->lang=$this->lang;
352
 
353
  // not much point in further processing if we don't have a function that does it
354
  if ($this->fetch_translate_func == null) {
377
  }
378
  }
379
  if ($newtext) {
380
+ if ($this->feed_fix) {
381
+ if (substr($newtext, 0, 4) == '&lt;') {
382
+ $newtext = html_entity_decode($newtext);
383
+ }
384
+ }
385
  $e->outertext = $newtext.$right;
386
+
387
  }
388
  }
389
 
403
  if ($ep->tag == 'phrase') {
404
  list ($translated_text, $source) = call_user_func_array($this->fetch_translate_func,array($ep->phrase, $this->lang));
405
  if (($this->is_edit_mode || ($this->is_auto_translate && $translated_text == null)) && $ep->inbody) {
406
+ // prevent duplicate translation (title = text)
407
  if (strpos($e->innertext,base64_url_encode($ep->phrase)) === false) {
408
+ //no need to translate span the same hidden phrase more than once
409
  if (!in_array($ep->phrase, $hidden_phrases)) {
410
  $span .= $this->create_edit_span($ep->phrase, $translated_text, $source, true)."</span>";
411
  //
420
  }
421
  }
422
  }
423
+ if ($newtext) {
424
+ $e->title = $newtext.$right;
425
+
426
+ }
427
+
428
  $e->outertext .= $span;
429
  // this is where we update in the outercase issue
430
  if ($e->parent->_[HDOM_INFO_OUTER]) {
433
 
434
  }
435
 
436
+ // now we handle the meta content - which is simpler because they can't be edited or auto-translated
437
+ // we also don't expect any father modifications here
438
+ foreach ($this->html->find('[content]') as $e) {
439
+ $right = '';
440
+ $newtext = '';
441
+
442
+ foreach ($e->nodes as $ep) {
443
+ if ($ep->tag == 'phrase') {
444
+ list ($translated_text, $source) = call_user_func_array($this->fetch_translate_func,array($ep->phrase, $this->lang));
445
+ if ($translated_text) {
446
+ list ($left, $right) = explode($ep->phrase, $e->content, 2);
447
+ $newtext .= $left.$translated_text;
448
+ $e->content = $right;
449
+ }
450
+ }
451
+ }
452
+ if ($newtext) {
453
+ $e->content = $newtext.$right;
454
+
455
+ }
456
+
457
+ }
458
+
459
  return $this->html;
460
  }
461
  }
core/utils.php CHANGED
@@ -17,9 +17,9 @@
17
  */
18
 
19
  /**
20
- *
21
  * Contains utility functions which are shared across the plugin.
22
- *
23
  */
24
 
25
  require_once("constants.php");
@@ -27,72 +27,68 @@ require_once("constants.php");
27
 
28
  /*
29
  * Update the given url to include language params.
30
- * param url - the original url to rewrite
31
  * param lang - language code
32
  * param is_edit - is running in edit mode.
33
  * param use_params_only - use only parameters as modifiers, i.e. not permalinks
34
  */
35
- function rewrite_url_lang_param($url, $lang, $is_edit, $use_params_only=FALSE)
36
- {
37
- global $home_url, $home_url_quoted, $enable_permalinks_rewrite;
38
-
39
  //
40
  //
41
  //
42
 
43
- $url = html_entity_decode($url, ENT_NOQUOTES);
44
  $url = str_replace('&#038;', '&', $url);
45
 
46
-
47
  //remove prev lang and edit params?
48
  $url = preg_replace("/(" . LANG_PARAM . "|" . EDIT_PARAM . ")=[^&]*/i", "", $url);
49
 
50
- if(!$enable_permalinks_rewrite)
51
- {
52
- //override the use only params - admin configured system to not touch permalinks
53
- $use_params_only = TRUE;
54
- }
55
-
56
- if($is_edit)
57
- {
58
- $params = EDIT_PARAM . '=1&';
59
-
60
- }
61
-
62
- if($use_params_only)
63
- {
64
- $params .= LANG_PARAM . "=$lang&";
65
- }
66
- else
67
- {
68
- $url = preg_replace("/$home_url_quoted\/(..(-..)?\/)?\/?/",
69
- "$home_url/$lang/", $url);
70
- }
71
-
72
- if($params)
73
- {
74
- //insert params to url
75
- $url = preg_replace("/(.+\/[^\?\#]*[\?]?)/", '$1?' . $params, $url);
76
 
77
- //Cleanup extra &
78
- $url = preg_replace("/&&+/", "&", $url);
 
 
79
 
80
- //Cleanup extra ?
81
- $url = preg_replace("/\?\?+/", "?", $url);
82
- }
83
 
84
- // more cleanups
85
- $url = preg_replace("/&$/", "", $url);
86
- $url = preg_replace("/\?$/", "", $url);
87
 
88
- $url = htmlentities($url, ENT_NOQUOTES);
 
 
89
 
90
- return $url;
 
 
91
  }
92
 
93
 
94
  /**
95
- * Encode a string as base 64 while avoiding characters which should be avoided
96
  * in uri, e.g. + is interpeted as a space.
97
  */
98
  function base64_url_encode($input) {
17
  */
18
 
19
  /**
20
+ *
21
  * Contains utility functions which are shared across the plugin.
22
+ *
23
  */
24
 
25
  require_once("constants.php");
27
 
28
  /*
29
  * Update the given url to include language params.
30
+ * param url - the original url to rewrite (expects full urls)
31
  * param lang - language code
32
  * param is_edit - is running in edit mode.
33
  * param use_params_only - use only parameters as modifiers, i.e. not permalinks
34
  */
35
+ function rewrite_url_lang_param($url, $lang, $is_edit, $use_params_only=FALSE) {
36
+ global $home_url, $home_url_quoted, $enable_permalinks_rewrite;
37
+
 
38
  //
39
  //
40
  //
41
 
42
+ $url = html_entity_decode($url, ENT_NOQUOTES);
43
  $url = str_replace('&#038;', '&', $url);
44
 
45
+
46
  //remove prev lang and edit params?
47
  $url = preg_replace("/(" . LANG_PARAM . "|" . EDIT_PARAM . ")=[^&]*/i", "", $url);
48
 
49
+ if(!$enable_permalinks_rewrite) {
50
+ //override the use only params - admin configured system to not touch permalinks
51
+ $use_params_only = TRUE;
52
+ }
53
+
54
+ $params ="";
55
+ if($is_edit) {
56
+ $params = EDIT_PARAM . '=1&';
57
+ }
58
+
59
+ if($use_params_only) {
60
+ $params .= LANG_PARAM . "=$lang&";
61
+ }
62
+ else {
63
+ $url = preg_replace("/$home_url_quoted\/(..(-..)?\/)?\/?/",
64
+ "$home_url/$lang/", $url);
65
+ }
66
+
 
 
 
 
 
 
 
 
67
 
68
+ if($params) {
69
+ //insert params to url
70
+ $url = preg_replace("/(.+\/[^\?\#]*[\?]?)/", '$1?' . $params, $url);
71
+
72
 
73
+ //Cleanup extra &
74
+ $url = preg_replace("/&&+/", "&", $url);
 
75
 
76
+ //Cleanup extra ?
77
+ $url = preg_replace("/\?\?+/", "?", $url);
78
+ }
79
 
80
+ // more cleanups
81
+ $url = preg_replace("/&$/", "", $url);
82
+ $url = preg_replace("/\?$/", "", $url);
83
 
84
+ $url = htmlentities($url, ENT_NOQUOTES);
85
+
86
+ return $url;
87
  }
88
 
89
 
90
  /**
91
+ * Encode a string as base 64 while avoiding characters which should be avoided
92
  * in uri, e.g. + is interpeted as a space.
93
  */
94
  function base64_url_encode($input) {
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: oferwald, amirperlman
3
  Donate link: http://transposh.org/
4
  Tags: translation, widget, filter, bilingual, multilingual, transposh, language, crowdsourcing, context, wiki, RTL, Hebrew, Spanish, French, Russian, English, Arabic, Portuguese
5
  Requires at least: 2.7
6
- Tested up to: 2.7.1
7
- Stable tag: 0.2.3
8
 
9
  Transposh filter allows in context quick translation of websites, it allows you to crowd-source the translation to your users
10
 
@@ -97,6 +97,15 @@ Just add the following line to your template:
97
  5. Widget style selection
98
 
99
  == Release notes ==
 
 
 
 
 
 
 
 
 
100
  * 2009/06/03 - 0.2.3
101
  * Revamped plugin setting page to a more useful one (code adapted from [code-styling.de](http://www.code-styling.de/))
102
  * Widget settings may be changed from settings page (thanks [Db0](http://dbzer0.com/))
3
  Donate link: http://transposh.org/
4
  Tags: translation, widget, filter, bilingual, multilingual, transposh, language, crowdsourcing, context, wiki, RTL, Hebrew, Spanish, French, Russian, English, Arabic, Portuguese
5
  Requires at least: 2.7
6
+ Tested up to: 2.8
7
+ Stable tag: 0.2.4
8
 
9
  Transposh filter allows in context quick translation of websites, it allows you to crowd-source the translation to your users
10
 
97
  5. Widget style selection
98
 
99
  == Release notes ==
100
+ * 2009/06/09 - 0.2.4
101
+ * Fixed bugs with database prefixes (thanks again [Mike](http://www.nostate.com/))
102
+ * Translation of keywords and description meta tags (thanks again [Mike](http://www.nostate.com/))
103
+ * Fix for RSS feeds provided in other languages
104
+ * Fixed compatability to show support for wordpress 2.8
105
+ * Support footer insertion of scripts in wordpress 2.8
106
+ * Fixed issues of html entities breaking when they should not (thanks [Karl](http://www.wp-plugin-archive.de/))
107
+ * Lang is now set in the headers for real
108
+ * Fixed compatability with themes using annoying query_posts with no consideration (thanks [Karl](http://www.wp-plugin-archive.de/))
109
  * 2009/06/03 - 0.2.3
110
  * Revamped plugin setting page to a more useful one (code adapted from [code-styling.de](http://www.code-styling.de/))
111
  * Widget settings may be changed from settings page (thanks [Db0](http://dbzer0.com/))
transposh.php CHANGED
@@ -2,9 +2,9 @@
2
  /*
3
  Plugin Name: Transposh Translation Filter
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.2.3
8
  Author URI: http://transposh.org/
9
  License: GPL (http://www.gnu.org/licenses/gpl.txt)
10
  */
@@ -40,54 +40,44 @@ $admin_msg;
40
  */
41
  function process_page(&$buffer) {
42
 
43
- global $wp_query, $lang, $is_edit_mode, $rtl_languages, $enable_auto_translate;
44
 
45
- $start_time = microtime(TRUE);
46
 
47
- // No language code - avoid further processing.
48
- /*if (!isset($wp_query->query_vars[LANG_PARAM]) && !get_option(ENABLE_DEFAULT_TRANSLATE))
49
- {
50
- return $buffer;
51
- }*/
52
-
53
  // Refrain from touching the administrative interface
54
- if(stripos($_SERVER['REQUEST_URI'],'/wp-admin/') !== FALSE)
55
- {
56
-
57
- return $buffer;
58
- }
59
-
60
- $lang = $wp_query->query_vars[LANG_PARAM];
61
- $default_lang = get_default_lang();
62
- if (!$lang) $lang = $default_lang;
63
-
64
- // Don't translate the default language unless specifically allowed to...
65
- if($lang == $default_lang && !get_option(ENABLE_DEFAULT_TRANSLATE))
66
- {
67
-
68
- return $buffer;
69
- }
70
-
71
- if (($wp_query->query_vars[EDIT_PARAM] == "1" || $wp_query->query_vars[EDIT_PARAM] == "true") &&
72
- is_editing_permitted())
73
- {
74
- $is_edit_mode = TRUE;
75
- }
76
-
77
- //translate the entire page
78
  $parse = new parser();
79
  $parse->fetch_translate_func = 'fetch_translation';
80
  $parse->url_rewrite_func = 'rewrite_url';
81
- $parse->dir_rtl = (in_array ($lang, $rtl_languages));
82
- $parse->lang = $lang;
83
- $parse->is_edit_mode = $is_edit_mode;
84
  $parse->is_auto_translate = $enable_auto_translate;
 
 
 
 
 
 
85
  $buffer = $parse->fix_html($buffer);
86
 
87
- $end_time = microtime(TRUE);
88
-
89
 
90
- return $buffer;
91
  }
92
 
93
  /*
@@ -95,24 +85,22 @@ function process_page(&$buffer) {
95
  * Note that at the time that this function is called the wp_query is not initialized,
96
  * which means that query parameters are not accessiable.
97
  */
98
- function init_global_vars()
99
- {
100
- global $home_url, $home_url_quoted, $tr_plugin_url, $enable_permalinks_rewrite, $wp_rewrite;
101
 
102
- $home_url = get_option('home');
103
  // Handle windows ('C:\wordpress')
104
  $local_dir = preg_replace("/\\\\/", "/", dirname(__FILE__));
105
  // Get last directory name
106
- $local_dir = preg_replace("/.*\//", "", $local_dir);
107
- $tr_plugin_url= WP_PLUGIN_URL .'/'. $local_dir;
108
 
109
- $home_url_quoted = preg_quote($home_url);
110
- $home_url_quoted = preg_replace("/\//", "\\/", $home_url_quoted);
111
 
112
- if($wp_rewrite->using_permalinks() && get_option(ENABLE_PERMALINKS_REWRITE))
113
- {
114
- $enable_permalinks_rewrite = TRUE;
115
- }
116
  }
117
 
118
  /*
@@ -120,186 +108,191 @@ function init_global_vars()
120
  * should not be translated.
121
  * Return the default language setting
122
  */
123
- function get_default_lang()
124
- {
125
- global $languages;
126
 
127
- $default = get_option(DEFAULT_LANG);
128
- if(!$languages[$default])
129
- {
130
- $default = "en";
131
- }
132
 
133
- return $default;
134
  }
135
 
136
  /*
137
  * Setup a buffer that will contain the contents of the html page.
138
  * Once processing is completed the buffer will go into the translation process.
139
  */
140
- function on_init()
141
- {
142
-
143
- init_global_vars();
144
-
145
- if ($_POST['translation_posted'])
146
- {
147
- update_translation();
148
- }
149
- elseif ($_GET['tr_token_hist']) {
150
- get_translation_history($_GET['tr_token_hist'], $_GET['lang']);
151
- }
152
- elseif ($_GET['tp_gif']) {
153
- $trans_gif_64 = "R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
154
- header("Content-type: image/gif");
155
- print(base64_decode($trans_gif_64));
156
- exit;
157
- }
158
- else
159
- {
160
- //set the callback for translating the page when it's done
161
- ob_start("process_page");
162
- }
163
  }
164
 
165
  /*
166
  * Page generation completed - flush buffer.
167
  */
168
- function on_shutdown()
169
- {
170
- ob_flush();
171
  }
172
 
173
  /*
174
  * Update the url rewrite rules to include language identifier
175
  */
176
- function update_rewrite_rules($rules){
177
-
178
 
179
- if(!get_option(ENABLE_PERMALINKS_REWRITE))
180
- {
181
-
182
- return $rules;
183
- }
184
 
185
- $newRules = array();
186
- $lang_prefix="([a-z]{2,2}(\-[a-z]{2,2})?)/";
187
 
188
- $lang_parameter= "&" . LANG_PARAM . '=$matches[1]';
189
 
190
- //catch the root url
191
- $newRules[$lang_prefix."?$"] = "index.php?lang=\$matches[1]";
192
-
193
 
194
- foreach ($rules as $key=>$value) {
195
- $original_key = $key;
196
- $original_value = $value;
197
 
198
- $key = $lang_prefix . $key;
199
 
200
- //Shift existing matches[i] two step forward as we pushed new elements
201
- //in the beginning of the expression
202
- for($i = 6; $i > 0; $i--)
203
- {
204
- $value = str_replace('['. $i .']', '['. ($i + 2) .']', $value);
205
- }
206
 
207
- $value .= $lang_parameter;
208
 
209
-
210
 
211
 
212
- $newRules[$key] = $value;
213
- $newRules[$original_key] = $original_value;
214
 
215
-
216
- }
217
 
218
-
219
- return $newRules;
220
  }
221
 
222
  /*
223
  * Let WordPress know which parameters are of interest to us.
224
  */
225
- function parameter_queryvars($qvars)
226
- {
227
- $qvars[] = LANG_PARAM;
228
- $qvars[] = EDIT_PARAM;
229
- return $qvars;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  }
231
 
232
  /*
233
  * Determine if the current user is allowed to translate.
234
  * Return TRUE if allowed to translate otherwise FALSE
235
  */
236
- function is_translator()
237
- {
238
- if(is_user_logged_in())
239
- {
240
- if(current_user_can(TRANSLATOR))
241
- {
242
- return TRUE;
243
- }
244
- }
245
-
246
- if(get_option(ANONYMOUS_TRANSLATION))
247
- {
248
- //if anonymous translation is allowed - let anyone enjoy it
249
- return TRUE;
250
- }
251
-
252
- return FALSE;
253
  }
254
 
255
  /*
256
  * Plugin activated.
257
  */
258
- function plugin_activate()
259
- {
260
- global $wp_rewrite;
261
-
262
 
263
- setup_db();
264
 
265
- add_filter('rewrite_rules_array', 'update_rewrite_rules');
266
- $wp_rewrite->flush_rules();
267
 
268
-
269
  }
270
 
271
  /*
272
  * Plugin deactivated.
273
  */
274
- function plugin_deactivate(){
275
- global $wp_rewrite;
276
-
277
 
278
- remove_filter('rewrite_rules_array', 'update_rewrite_rules');
279
- $wp_rewrite->flush_rules();
280
 
281
-
282
  }
283
 
284
  /*
285
  * Callback from admin_notices - display error message to the admin.
286
  */
287
- function plugin_install_error()
288
- {
289
- global $admin_msg;
290
-
291
 
292
- echo '<div class="updated"><p>';
293
- echo 'Error has occured in the installation process of the translation plugin: <br>';
294
 
295
- echo $admin_msg;
296
 
297
- if (function_exists('deactivate_plugins') ) {
298
- deactivate_plugins(get_plugin_name(), "translate.php");
299
- echo '<br> This plugin has been automatically deactivated.';
300
- }
301
 
302
- echo '</p></div>';
303
  }
304
 
305
  /*
@@ -307,31 +300,28 @@ function plugin_install_error()
307
  * to check that the plugin loaded successfully else trigger notification
308
  * to the admin and deactivate plugin.
309
  */
310
- function plugin_loaded()
311
- {
312
- global $admin_msg;
313
-
314
-
315
- $db_version = get_option(TRANSPOSH_DB_VERSION);
316
-
317
- if ($db_version != DB_VERSION)
318
- {
319
- setup_db();
320
- //$admin_msg = "Translation database version ($db_version) is not comptabile with this plugin (". DB_VERSION . ") <br>";
321
-
322
-
323
- //Some error occured - notify admin and deactivate plugin
324
- //add_action('admin_notices', 'plugin_install_error');
325
- }
326
-
327
- if ($db_version != DB_VERSION)
328
- {
329
- $admin_msg = "Failed to locate the translation table <em> " . TRANSLATIONS_TABLE . "</em> in local database. <br>";
330
-
331
-
332
- //Some error occured - notify admin and deactivate plugin
333
- add_action('admin_notices', 'plugin_install_error');
334
- }
335
  }
336
 
337
  /*
@@ -339,33 +329,31 @@ function plugin_loaded()
339
  * Keep only the file name and its containing directory. Don't use the full
340
  * path as it will break when using symbollic links.
341
  */
342
- function get_plugin_name()
343
- {
344
- $file = __FILE__;
345
- $file = str_replace('\\','/',$file); // sanitize for Win32 installs
346
- $file = preg_replace('|/+|','/', $file); // remove any duplicate slash
347
-
348
- //keep only the file name and its parent directory
349
- $file = preg_replace('/.*\/([^\/]+\/[^\/]+)$/', '$1', $file);
350
-
351
- return $file;
352
  }
353
 
354
  /*
355
  * Add custom css, i.e. transposh.css
356
  */
357
  function add_transposh_css() {
358
- global $tr_plugin_url;
359
-
360
- if(!is_editing_permitted() && !is_auto_translate_permitted())
361
- {
362
- //translation not allowed - no need for the transposh.css
363
- return;
364
- }
365
- //include the transposh.css
366
- wp_enqueue_style("transposh","$tr_plugin_url/css/transposh.css",array(),'0.2.3');
367
- wp_enqueue_style("jquery","http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/themes/ui-lightness/jquery-ui.css",array(),'1.0');
368
-
369
  }
370
 
371
  /*
@@ -373,42 +361,37 @@ function add_transposh_css() {
373
  * version of the page.
374
  */
375
  function add_transposh_js() {
376
- global $tr_plugin_url, $wp_query, $lang, $home_url, $enable_auto_translate;
377
-
378
- $enable_auto_translate = is_auto_translate_permitted();
379
- if(!is_editing_permitted() && !$enable_auto_translate)
380
- {
381
- //translation not allowed - no need for any js.
382
- return;
383
- }
384
 
385
- $is_edit_param_enabled = $wp_query->query_vars[EDIT_PARAM];
 
 
 
 
386
 
387
- if (!$is_edit_param_enabled && !$enable_auto_translate)
388
- {
389
- //Not in any translation mode - no need for any js.
390
- return;
391
- }
392
 
393
  $options = get_option(WIDGET_TRANSPOSH);
394
 
395
- if($is_edit_param_enabled)
396
- {
397
- $edit_mode = "&".EDIT_PARAM."=y";
398
- }
399
 
400
- if($is_edit_param_enabled || $options['progressbar']) {
401
- wp_enqueue_script("jqueryui","http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js",array("jquery"),'1.7.1');
 
 
 
 
 
 
 
 
402
  }
403
-
404
- if($is_edit_param_enabled || $enable_auto_translate)
405
- {
406
- $post_url = $home_url . '/index.php';
407
- wp_deregister_script('jquery');
408
- wp_enqueue_script("jquery","http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js",array(),'1.3.2');
409
- wp_enqueue_script("google","http://www.google.com/jsapi",array(),'1');
410
- wp_enqueue_script("transposh","$tr_plugin_url/js/transposh.js?post_url=$post_url{$edit_mode}&lang={$lang}&prefix=".SPAN_PREFIX,array("jquery"),'0.2.3');
411
- }
412
  }
413
 
414
 
@@ -418,28 +401,23 @@ function add_transposh_js() {
418
  *
419
  * @return TRUE if translation allowed otherwise FALSE
420
  */
421
- function is_editing_permitted()
422
- {
423
- global $wp_query ,$lang;
424
-
425
- if(!is_translator()) return FALSE;
426
-
427
- $lang = $wp_query->query_vars[LANG_PARAM];
428
- if (get_option(ENABLE_DEFAULT_TRANSLATE) && !$lang) $lang = get_default_lang();
429
-
430
- if (!$lang) return FALSE;
431
-
432
- return is_editable_lang($lang);
433
  }
434
 
435
  /**
436
  * Determine if the given language in on the list of editable languages
437
  * @return TRUE if editable othewise FALSE
438
  */
439
- function is_editable_lang($lang)
440
- {
441
- $editable_langs = get_option(EDITABLE_LANGS);
442
- return (strpos($editable_langs, $lang) === FALSE) ? FALSE : TRUE;
443
  }
444
 
445
 
@@ -450,19 +428,13 @@ function is_editable_lang($lang)
450
  *
451
  * @return TRUE if automatic translation allowed otherwise FALSE
452
  */
453
- function is_auto_translate_permitted()
454
- {
455
- global $wp_query ,$lang;
456
 
457
 
458
- if(!get_option(ENABLE_AUTO_TRANSLATE, 1)) return FALSE;
459
-
460
- $lang = $wp_query->query_vars[LANG_PARAM];
461
- if (get_option(ENABLE_DEFAULT_TRANSLATE) && !$lang) $lang = get_default_lang();
462
-
463
- if (!$lang) return FALSE;
464
 
465
- return is_editable_lang($lang);
466
  }
467
  /**
468
  * Callback from parser allowing to overide the global setting of url rewriting using permalinks.
@@ -471,39 +443,43 @@ function is_auto_translate_permitted()
471
  * @param $href
472
  * @return TRUE if parameters should be used instead of rewriting as a permalink
473
  */
474
- function rewrite_url($href)
475
- {
476
- global $lang, $is_edit_mode, $enable_permalinks_rewrite, $home_url;
477
- $use_params = FALSE;
478
 
479
 
480
  // Ignore urls not from this site
481
- if(stripos($href, $home_url) === FALSE)
482
- {
483
- return $href;
484
- }
485
-
486
- // don't fix links pointing to real files as it will cause that the
487
- // web server will not be able to locate them
488
- if(stripos($href, '/wp-admin') !== FALSE ||
489
- stripos($href, '/wp-content') !== FALSE ||
490
- stripos($href, '/wp-login') !== FALSE ||
491
- stripos($href, '/.php') !== FALSE)
492
- {
493
- return $href;
494
- }
495
- $use_params = !$enable_permalinks_rewrite;
496
-
497
- $href = rewrite_url_lang_param($href, $lang, $is_edit_mode, $use_params);
498
 
499
  return $href;
500
  }
501
 
 
 
 
 
 
502
  //Register callbacks
503
  add_filter('query_vars', 'parameter_queryvars' );
 
 
 
504
  add_action('wp_print_styles', 'add_transposh_css');
505
  add_action('wp_print_scripts', 'add_transposh_js');
506
-
507
  add_action('init', 'on_init');
508
  add_action('shutdown', 'on_shutdown');
509
 
2
  /*
3
  Plugin Name: Transposh Translation Filter
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.2.4
8
  Author URI: http://transposh.org/
9
  License: GPL (http://www.gnu.org/licenses/gpl.txt)
10
  */
40
  */
41
  function process_page(&$buffer) {
42
 
43
+ global $wp_query, $rtl_languages, $enable_auto_translate;
44
 
45
+ $start_time = microtime(TRUE);
46
 
 
 
 
 
 
 
47
  // Refrain from touching the administrative interface
48
+ if(stripos($_SERVER['REQUEST_URI'],'/wp-admin/') !== FALSE) {
49
+
50
+ return $buffer;
51
+ }
52
+
53
+
54
+ // Don't translate the default language unless specifically allowed to...
55
+ $default_lang = get_default_lang();
56
+ if($GLOBALS['lang'] == $default_lang && !get_option(ENABLE_DEFAULT_TRANSLATE)) {
57
+
58
+ return $buffer;
59
+ }
60
+
61
+ //translate the entire page
 
 
 
 
 
 
 
 
 
 
62
  $parse = new parser();
63
  $parse->fetch_translate_func = 'fetch_translation';
64
  $parse->url_rewrite_func = 'rewrite_url';
65
+ $parse->dir_rtl = (in_array ($GLOBALS['lang'], $rtl_languages));
66
+ $parse->lang = $GLOBALS['lang'];
67
+ $parse->is_edit_mode = $GLOBALS['is_edit_mode'];
68
  $parse->is_auto_translate = $enable_auto_translate;
69
+ if(stripos($_SERVER['REQUEST_URI'],'/feed/') !== FALSE) {
70
+
71
+ $parse->is_auto_translate = false;
72
+ $parse->is_edit_mode = false;
73
+ $parse->feed_fix = true;
74
+ }
75
  $buffer = $parse->fix_html($buffer);
76
 
77
+ $end_time = microtime(TRUE);
78
+
79
 
80
+ return $buffer;
81
  }
82
 
83
  /*
85
  * Note that at the time that this function is called the wp_query is not initialized,
86
  * which means that query parameters are not accessiable.
87
  */
88
+ function init_global_vars() {
89
+ global $home_url, $home_url_quoted, $tr_plugin_url, $enable_permalinks_rewrite, $wp_rewrite;
 
90
 
91
+ $home_url = get_option('home');
92
  // Handle windows ('C:\wordpress')
93
  $local_dir = preg_replace("/\\\\/", "/", dirname(__FILE__));
94
  // Get last directory name
95
+ $local_dir = preg_replace("/.*\//", "", $local_dir);
96
+ $tr_plugin_url= WP_PLUGIN_URL .'/'. $local_dir;
97
 
98
+ $home_url_quoted = preg_quote($home_url);
99
+ $home_url_quoted = preg_replace("/\//", "\\/", $home_url_quoted);
100
 
101
+ if($wp_rewrite->using_permalinks() && get_option(ENABLE_PERMALINKS_REWRITE)) {
102
+ $enable_permalinks_rewrite = TRUE;
103
+ }
 
104
  }
105
 
106
  /*
108
  * should not be translated.
109
  * Return the default language setting
110
  */
111
+ function get_default_lang() {
112
+ global $languages;
 
113
 
114
+ $default = get_option(DEFAULT_LANG);
115
+ if(!$languages[$default]) {
116
+ $default = "en";
117
+ }
 
118
 
119
+ return $default;
120
  }
121
 
122
  /*
123
  * Setup a buffer that will contain the contents of the html page.
124
  * Once processing is completed the buffer will go into the translation process.
125
  */
126
+ function on_init() {
127
+
128
+ init_global_vars();
129
+
130
+ if (isset($_POST['translation_posted'])) {
131
+ update_translation();
132
+ }
133
+ elseif (isset($_GET['tr_token_hist'])) {
134
+ get_translation_history($_GET['tr_token_hist'], $_GET['lang']);
135
+ }
136
+ elseif (isset($_GET['tp_gif'])) {
137
+ $trans_gif_64 = "R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
138
+ header("Content-type: image/gif");
139
+ print(base64_decode($trans_gif_64));
140
+ exit;
141
+ }
142
+ else {
143
+ //set the callback for translating the page when it's done
144
+ ob_start("process_page");
145
+ }
 
 
 
146
  }
147
 
148
  /*
149
  * Page generation completed - flush buffer.
150
  */
151
+ function on_shutdown() {
152
+ ob_flush();
 
153
  }
154
 
155
  /*
156
  * Update the url rewrite rules to include language identifier
157
  */
158
+ function update_rewrite_rules($rules) {
159
+
160
 
161
+ if(!get_option(ENABLE_PERMALINKS_REWRITE)) {
162
+
163
+ return $rules;
164
+ }
 
165
 
166
+ $newRules = array();
167
+ $lang_prefix="([a-z]{2,2}(\-[a-z]{2,2})?)/";
168
 
169
+ $lang_parameter= "&" . LANG_PARAM . '=$matches[1]';
170
 
171
+ //catch the root url
172
+ $newRules[$lang_prefix."?$"] = "index.php?lang=\$matches[1]";
173
+
174
 
175
+ foreach ($rules as $key=>$value) {
176
+ $original_key = $key;
177
+ $original_value = $value;
178
 
179
+ $key = $lang_prefix . $key;
180
 
181
+ //Shift existing matches[i] two step forward as we pushed new elements
182
+ //in the beginning of the expression
183
+ for($i = 6; $i > 0; $i--) {
184
+ $value = str_replace('['. $i .']', '['. ($i + 2) .']', $value);
185
+ }
 
186
 
187
+ $value .= $lang_parameter;
188
 
189
+
190
 
191
 
192
+ $newRules[$key] = $value;
193
+ $newRules[$original_key] = $original_value;
194
 
195
+
196
+ }
197
 
198
+
199
+ return $newRules;
200
  }
201
 
202
  /*
203
  * Let WordPress know which parameters are of interest to us.
204
  */
205
+ function parameter_queryvars($vars) {
206
+
207
+ $vars[] = LANG_PARAM;
208
+ $vars[] = EDIT_PARAM;
209
+
210
+ return $vars;
211
+ }
212
+
213
+ /**
214
+ * Grabs and set the global language and edit params, they should be here
215
+ * @param <type> $wp - here we get the WP class
216
+ */
217
+ function on_parse_request($wp) {
218
+
219
+
220
+ $GLOBALS['lang'] = $wp->query_vars[LANG_PARAM];
221
+ if (!$GLOBALS['lang']) $GLOBALS['lang'] = get_default_lang();
222
+
223
+ if ($wp->query_vars[EDIT_PARAM] && is_editing_permitted()) {
224
+ $GLOBALS['is_edit_mode'] = true;
225
+ } else {
226
+ $GLOBALS['is_edit_mode'] = false;
227
+ }
228
+
229
  }
230
 
231
  /*
232
  * Determine if the current user is allowed to translate.
233
  * Return TRUE if allowed to translate otherwise FALSE
234
  */
235
+ function is_translator() {
236
+ if(is_user_logged_in()) {
237
+ if(current_user_can(TRANSLATOR)) {
238
+ return TRUE;
239
+ }
240
+ }
241
+
242
+ if(get_option(ANONYMOUS_TRANSLATION)) {
243
+ //if anonymous translation is allowed - let anyone enjoy it
244
+ return TRUE;
245
+ }
246
+
247
+ return FALSE;
 
 
 
 
248
  }
249
 
250
  /*
251
  * Plugin activated.
252
  */
253
+ function plugin_activate() {
254
+ global $wp_rewrite;
255
+
 
256
 
257
+ setup_db();
258
 
259
+ add_filter('rewrite_rules_array', 'update_rewrite_rules');
260
+ $wp_rewrite->flush_rules();
261
 
262
+
263
  }
264
 
265
  /*
266
  * Plugin deactivated.
267
  */
268
+ function plugin_deactivate() {
269
+ global $wp_rewrite;
270
+
271
 
272
+ remove_filter('rewrite_rules_array', 'update_rewrite_rules');
273
+ $wp_rewrite->flush_rules();
274
 
275
+
276
  }
277
 
278
  /*
279
  * Callback from admin_notices - display error message to the admin.
280
  */
281
+ function plugin_install_error() {
282
+ global $admin_msg;
283
+
 
284
 
285
+ echo '<div class="updated"><p>';
286
+ echo 'Error has occured in the installation process of the translation plugin: <br>';
287
 
288
+ echo $admin_msg;
289
 
290
+ if (function_exists('deactivate_plugins') ) {
291
+ deactivate_plugins(get_plugin_name(), "translate.php");
292
+ echo '<br> This plugin has been automatically deactivated.';
293
+ }
294
 
295
+ echo '</p></div>';
296
  }
297
 
298
  /*
300
  * to check that the plugin loaded successfully else trigger notification
301
  * to the admin and deactivate plugin.
302
  */
303
+ function plugin_loaded() {
304
+ global $admin_msg;
305
+
306
+
307
+ $db_version = get_option(TRANSPOSH_DB_VERSION);
308
+
309
+ if ($db_version != DB_VERSION) {
310
+ setup_db();
311
+ //$admin_msg = "Translation database version ($db_version) is not comptabile with this plugin (". DB_VERSION . ") <br>";
312
+
313
+
314
+ //Some error occured - notify admin and deactivate plugin
315
+ //add_action('admin_notices', 'plugin_install_error');
316
+ }
317
+
318
+ if ($db_version != DB_VERSION) {
319
+ $admin_msg = "Failed to locate the translation table <em> " . TRANSLATIONS_TABLE . "</em> in local database. <br>";
320
+
321
+
322
+ //Some error occured - notify admin and deactivate plugin
323
+ add_action('admin_notices', 'plugin_install_error');
324
+ }
 
 
 
325
  }
326
 
327
  /*
329
  * Keep only the file name and its containing directory. Don't use the full
330
  * path as it will break when using symbollic links.
331
  */
332
+ function get_plugin_name() {
333
+ $file = __FILE__;
334
+ $file = str_replace('\\','/',$file); // sanitize for Win32 installs
335
+ $file = preg_replace('|/+|','/', $file); // remove any duplicate slash
336
+
337
+ //keep only the file name and its parent directory
338
+ $file = preg_replace('/.*\/([^\/]+\/[^\/]+)$/', '$1', $file);
339
+
340
+ return $file;
 
341
  }
342
 
343
  /*
344
  * Add custom css, i.e. transposh.css
345
  */
346
  function add_transposh_css() {
347
+ global $tr_plugin_url;
348
+
349
+ if(!is_editing_permitted() && !is_auto_translate_permitted()) {
350
+ //translation not allowed - no need for the transposh.css
351
+ return;
352
+ }
353
+ //include the transposh.css
354
+ wp_enqueue_style("transposh","$tr_plugin_url/css/transposh.css",array(),'0.2.4');
355
+ wp_enqueue_style("jquery","http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/themes/ui-lightness/jquery-ui.css",array(),'1.0');
356
+
 
357
  }
358
 
359
  /*
361
  * version of the page.
362
  */
363
  function add_transposh_js() {
364
+ global $tr_plugin_url, $wp_query, $home_url, $enable_auto_translate, $wp_version;
 
 
 
 
 
 
 
365
 
366
+ $enable_auto_translate = is_auto_translate_permitted();
367
+ if(!is_editing_permitted() && !$enable_auto_translate) {
368
+ //translation not allowed - no need for any js.
369
+ return;
370
+ }
371
 
372
+ if (!$GLOBALS['is_edit_mode'] && !$enable_auto_translate) {
373
+ //Not in any translation mode - no need for any js.
374
+ return;
375
+ }
 
376
 
377
  $options = get_option(WIDGET_TRANSPOSH);
378
 
379
+ $edit_mode = "";
380
+ if($GLOBALS['is_edit_mode']) {
381
+ $edit_mode = "&".EDIT_PARAM."=y";
382
+ }
383
 
384
+ if($GLOBALS['is_edit_mode'] || $options['progressbar']) {
385
+ wp_enqueue_script("jqueryui","http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js",array("jquery"),'1.7.1',get_option(ENABLE_FOOTER_SCRIPTS));
386
+ }
387
+
388
+ if($GLOBALS['is_edit_mode'] || $enable_auto_translate) {
389
+ $post_url = $home_url . '/index.php';
390
+ wp_deregister_script('jquery');
391
+ wp_enqueue_script("jquery","http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js",array(),'1.3.2', get_option(ENABLE_FOOTER_SCRIPTS));
392
+ wp_enqueue_script("google","http://www.google.com/jsapi",array(),'1',get_option(ENABLE_FOOTER_SCRIPTS));
393
+ wp_enqueue_script("transposh","$tr_plugin_url/js/transposh.js?post_url=$post_url{$edit_mode}&lang={$GLOBALS['lang']}&prefix=".SPAN_PREFIX,array("jquery"),'0.2.4',get_option(ENABLE_FOOTER_SCRIPTS));
394
  }
 
 
 
 
 
 
 
 
 
395
  }
396
 
397
 
401
  *
402
  * @return TRUE if translation allowed otherwise FALSE
403
  */
404
+ function is_editing_permitted() {
405
+ global $wp_query;
406
+ // editing is permitted for translators only
407
+ if(!is_translator()) return FALSE;
408
+ // and only on the non-default lang (unless strictly specified)
409
+ if (!get_option(ENABLE_DEFAULT_TRANSLATE) && $GLOBALS['lang'] == get_default_lang()) return false;
410
+
411
+ return is_editable_lang($GLOBALS['lang']);
 
 
 
 
412
  }
413
 
414
  /**
415
  * Determine if the given language in on the list of editable languages
416
  * @return TRUE if editable othewise FALSE
417
  */
418
+ function is_editable_lang($language) {
419
+ $editable_langs = get_option(EDITABLE_LANGS);
420
+ return (strpos($editable_langs, $language) === FALSE) ? FALSE : TRUE;
 
421
  }
422
 
423
 
428
  *
429
  * @return TRUE if automatic translation allowed otherwise FALSE
430
  */
431
+ function is_auto_translate_permitted() {
432
+ global $wp_query;
 
433
 
434
 
435
+ if(!get_option(ENABLE_AUTO_TRANSLATE, 1)) return FALSE;
 
 
 
 
 
436
 
437
+ return is_editable_lang($GLOBALS['lang']);
438
  }
439
  /**
440
  * Callback from parser allowing to overide the global setting of url rewriting using permalinks.
443
  * @param $href
444
  * @return TRUE if parameters should be used instead of rewriting as a permalink
445
  */
446
+ function rewrite_url($href) {
447
+ global $enable_permalinks_rewrite, $home_url;
448
+ $use_params = FALSE;
 
449
 
450
 
451
  // Ignore urls not from this site
452
+ if(stripos($href, $home_url) === FALSE) {
453
+ return $href;
454
+ }
455
+
456
+ // don't fix links pointing to real files as it will cause that the
457
+ // web server will not be able to locate them
458
+ if(stripos($href, '/wp-admin') !== FALSE ||
459
+ stripos($href, '/wp-content') !== FALSE ||
460
+ stripos($href, '/wp-login') !== FALSE ||
461
+ stripos($href, '/.php') !== FALSE) {
462
+ return $href;
463
+ }
464
+ $use_params = !$enable_permalinks_rewrite;
465
+
466
+ $href = rewrite_url_lang_param($href, $GLOBALS['lang'], $GLOBALS['is_edit_mode'], $use_params);
 
 
467
 
468
  return $href;
469
  }
470
 
471
+ function plugin_action_links( $links ) {
472
+
473
+ return array_merge( array('<a href="' . admin_url('options-general.php?page='.TRANSPOSH_ADMIN_PAGE_NAME) . '">Settings</a>'), $links );
474
+ }
475
+
476
  //Register callbacks
477
  add_filter('query_vars', 'parameter_queryvars' );
478
+ add_action('parse_request', 'on_parse_request');
479
+
480
+ add_filter('plugin_action_links_' .preg_replace( '|^' . preg_quote(WP_PLUGIN_DIR, '|') . '/|', '', __FILE__ ), 'plugin_action_links');
481
  add_action('wp_print_styles', 'add_transposh_css');
482
  add_action('wp_print_scripts', 'add_transposh_js');
 
483
  add_action('init', 'on_init');
484
  add_action('shutdown', 'on_shutdown');
485
 
transposh_admin.php CHANGED
@@ -29,26 +29,25 @@ define ("TR_NONCE","transposh_nonce");
29
  /*
30
  * Insert supported languages section in admin page
31
  */
32
- function insert_supported_langs()
33
- {
34
  global $languages, $tr_plugin_url;
35
 
36
  echo
37
  '<script type="text/javascript">'.
38
  'function chbx_change(lang)'.
39
  '{'.
40
- 'jQuery("#"+lang+"_edit").attr("checked",jQuery("#"+lang+"_view").attr("checked"))'.
41
  '}'.
42
  'jQuery(document).ready(function() {'.
43
- 'jQuery("#tr_anon").click(function() {'.
44
- 'if (jQuery("#tr_anon").attr("checked")) {'.
45
- 'jQuery(".tr_editable").css("display","none");'.
46
- '} else {'.
47
- 'jQuery(".tr_editable").css("display","");'.
48
- '}'.
49
- '});'.
50
  '});'.
51
- '</script>';
52
  echo '<table class="'.NO_TRANSLATE_CLASS.'" style="width: 100%"><tr>';
53
 
54
  // we will hide the translatable column if anonymous can translate anyway
@@ -58,26 +57,25 @@ function insert_supported_langs()
58
  for($hdr=0; $hdr < $columns; $hdr++) {
59
  $extrapad = ($hdr != $columns - 1) ? ";padding-right: 40px" : '';
60
  echo '<th style="text-align:left; width:'.(100/$columns).'%">Language</th>'.
61
- '<th title="Is this language user selectable?">Viewable</th>'.
62
- '<th title="Is this language visible for translators?"'.$extrastyle.' class="tr_editable">Translatable</th>'.
63
- '<th>Default</th>'.
64
- '<th style="text-align:left;width: 80px'.$extrapad.'" title="Can we auto-translate this language?">Auto?</th>';
65
  }
66
  echo '</tr>';
67
 
68
- foreach($languages as $code => $lang)
69
- {
70
  list ($language,$flag,$autot) = explode (",",$lang);
71
  if(!($i % $columns)) echo '<tr>';
72
  $i++;
73
 
74
  echo "<td><img src=\"$tr_plugin_url/img/flags/$flag.png\" alt=\"\"/>&nbsp;$language</td>";
75
  echo '<td align="center"><input type="checkbox" id="' . $code .'_view" name="' .
76
- $code . '_view" onchange="chbx_change(\'' . $code . '\')" ' . is_viewable($code) . '/></td>';
77
  echo '<td class="tr_editable"'.$extrastyle.' align="center"><input type="checkbox" id="' . $code . '_edit" name="' .
78
- $code . '_edit" ' . is_editable($code). '/></td>';
79
  echo "<td align=\"center\"><input type=\"radio\" name=\"default_lang\" value=\"$code\" " .
80
- is_default_lang($code). "/></td>";
81
  // TODO: Add icons?
82
  echo "<td>".($autot ? "Y" : "N")."</td>";
83
 
@@ -92,8 +90,7 @@ function insert_supported_langs()
92
  * Determine if the given language code is currentlly editable
93
  * Return 'checked' if true otherwise ""
94
  */
95
- function is_editable($code)
96
- {
97
  $langs = get_option(EDITABLE_LANGS);
98
  return (strpos($langs, $code) !== FALSE) ? 'checked="checked"' : '';
99
  }
@@ -102,8 +99,7 @@ function is_editable($code)
102
  * Determine if the given language code is currentlly viewable
103
  * Return 'checked' if true otherwise ""
104
  */
105
- function is_viewable($code)
106
- {
107
  $langs = get_option(VIEWABLE_LANGS);
108
  return (strpos($langs, $code) !== FALSE) ? 'checked="checked"' : '';
109
  }
@@ -112,8 +108,7 @@ function is_viewable($code)
112
  * Determine if the given language code is currentlly the default language
113
  * Return 'checked' if true otherwise ""
114
  */
115
- function is_default_lang($code)
116
- {
117
  global $languages;
118
  $default = get_option(DEFAULT_LANG);
119
  if(!$languages[$default]) $default = "en";
@@ -123,14 +118,12 @@ function is_default_lang($code)
123
  /*
124
  * Insert permissions section in the admin page
125
  */
126
- function insert_permissions()
127
- {
128
  global $wp_roles;
129
  //display known roles and their permission to translate
130
- foreach($wp_roles->get_names() as $role_name => $something)
131
- {
132
  echo '<input type="checkbox" value="1" name="'.$role_name.'" '.can_translate($role_name).
133
- '/> '.ucfirst($role_name).'&nbsp;&nbsp;&nbsp;';
134
  }
135
  //Add our own custom role
136
  echo '<input id="tr_anon" type="checkbox" value="1" name="anonymous" '. can_translate('anonymous') . '/> Anonymous';
@@ -140,90 +133,90 @@ function insert_permissions()
140
  * Insert the option to enable/disable rewrite of perlmalinks.
141
  * When disabled only parameters will be used to identify the current language.
142
  */
143
- function insert_permalink_rewrite_option()
144
- {
145
  $checked = (get_option(ENABLE_PERMALINKS_REWRITE)) ? 'checked="checked"' :'';
146
  echo '<input type="checkbox" value="1" name="enable_permalinks" '. $checked . '/> '.
147
- 'Rewrite URLs to be search engine friendly, '.
148
- 'e.g. (http://wordpress.org/<strong>en</strong>). '.
149
- 'Requires that permalinks will be enabled.';
 
 
 
 
 
 
 
 
 
 
150
  }
151
 
152
  /*
153
  * Insert the option to enable/disable automatic translation.
154
  * Enabled by default.
155
  */
156
- function insert_auto_translate_option()
157
- {
158
  $checked = (get_option(ENABLE_AUTO_TRANSLATE,1)) ? 'checked="checked"' : '';
159
  echo '<input type="checkbox" value="1" name="enable_autotranslate" '.$checked.'/> '.
160
- 'Allow automatic translation of pages (currently using Google Translate)';
161
  }
162
 
163
  /*
164
  * Insert the option to enable/disable default language translation.
165
  * Disabled by default.
166
  */
167
- function insert_default_translate_option()
168
- {
169
  $checked = (get_option(ENABLE_DEFAULT_TRANSLATE,0)) ? 'checked="checked"' : '';
170
  echo '<input type="checkbox" value="1" name="enable_defaulttranslate" '.$checked.'/> '.
171
- 'Allow translation of default language - useful for sites with more than one major language';
172
  }
173
  //
174
  /*
175
  * Indicates whether the given role can translate.
176
  * Return either "checked" or ""
177
  */
178
- function can_translate($role_name)
179
- {
180
  global $wp_roles;
181
- if($role_name != 'anonymous')
182
- {
183
  $role = $wp_roles->get_role($role_name);
184
  if(isset($role) && $role->has_cap(TRANSLATOR))
185
- return 'checked="checked"';
186
 
187
  }
188
  else
189
- return (get_option(ANONYMOUS_TRANSLATION,1)) ? 'checked="checked"' : '';
190
  }
191
  //
192
  /*
193
  * Handle newly posted admin options.
194
  */
195
- function update_admin_options()
196
- {
197
 
198
  global $wp_roles, $languages;
199
  $viewable_langs = array();
200
  $editable_langs = array();
201
 
202
  //update roles and capabilities
203
- foreach($wp_roles->get_names() as $role_name => $something)
204
- {
205
  $role = $wp_roles->get_role($role_name);
206
  if($_POST[$role_name] == "1")
207
- $role->add_cap(TRANSLATOR);
208
  else
209
- $role->remove_cap(TRANSLATOR);
210
  }
211
 
212
  //Anonymous needs to be handled differently as it does not have a role
213
  update_option(ANONYMOUS_TRANSLATION, ($_POST['anonymous']) ? 1 : 0);
214
 
215
  //Update the list of supported/editable languages
216
- foreach($languages as $code => $lang)
217
- {
218
- if($_POST[$code . '_view'])
219
- {
220
  $viewable_langs[$code] = $code;
221
  // force that every viewable lang is editable
222
  $editable_langs[$code] = $code;
223
  }
224
 
225
- if($_POST[$code . '_edit'])
226
- {
227
  $editable_langs[$code] = $code;
228
  }
229
  }
@@ -232,8 +225,7 @@ function update_admin_options()
232
  update_option(EDITABLE_LANGS, implode(',', $editable_langs));
233
  update_option(DEFAULT_LANG, $_POST['default_lang']);
234
 
235
- if(get_option(ENABLE_PERMALINKS_REWRITE) != $_POST['enable_permalinks'])
236
- {
237
  global $wp_rewrite;
238
  update_option(ENABLE_PERMALINKS_REWRITE, $_POST['enable_permalinks']);
239
 
@@ -242,20 +234,23 @@ function update_admin_options()
242
  $wp_rewrite->flush_rules();
243
  }
244
 
 
 
 
245
  if(get_option(ENABLE_AUTO_TRANSLATE,1) != $_POST['enable_autotranslate'])
246
- update_option(ENABLE_AUTO_TRANSLATE, $_POST['enable_autotranslate']);
247
 
248
  if(get_option(ENABLE_DEFAULT_TRANSLATE) != $_POST['enable_defaulttranslate'])
249
- update_option(ENABLE_DEFAULT_TRANSLATE, $_POST['enable_defaulttranslate']);
250
 
251
  }
252
 
253
  //class that reperesent the complete plugin
254
  class transposh_plugin {
255
 
256
- //constructor of class, PHP4 compatible construction for backward compatibility
257
  function transposh_plugin() {
258
- //add filter for WordPress 2.8 changed backend box system !
259
  add_filter('screen_layout_columns', array(&$this, 'on_screen_layout_columns'), 10, 2);
260
  //add some help
261
  add_filter('contextual_help_list', array(&$this, 'on_contextual_help'),100,2);
@@ -277,15 +272,15 @@ class transposh_plugin {
277
  function on_contextual_help($filterVal,$screen) {
278
  if($screen == "settings_page_transposh") {
279
  $filterVal["settings_page_transposh"] = '<p>Transposh makes your blog translatable</p>'.
280
- '<a href="http://transposh.org/">Plugin homepage</a><br/>'.
281
- '<a href="http://transposh.org/faq/">Frequently asked questions</a>';
282
  }
283
  return $filterVal;
284
  }
285
 
286
  //extend the admin menu
287
  function on_admin_menu() {
288
- //add our own option page, you can also add it to different sections or use your own one
289
  $this->pagehook = add_options_page('Transposh control center', "Transposh", 'manage_options', TRANSPOSH_ADMIN_PAGE_NAME, array(&$this, 'on_show_page'));
290
  //register callback gets call prior your own page gets rendered
291
  add_action('load-'.$this->pagehook, array(&$this, 'on_load_page'));
@@ -293,7 +288,7 @@ class transposh_plugin {
293
 
294
  //will be executed if wordpress core detects this page has to be rendered
295
  function on_load_page() {
296
- //ensure, that the needed javascripts been loaded to allow drag/drop, expand/collapse and hide/show of boxes
297
  wp_enqueue_script('common');
298
  wp_enqueue_script('wp-lists');
299
  wp_enqueue_script('postbox');
@@ -310,7 +305,7 @@ class transposh_plugin {
310
 
311
  //executed to show the plugins complete admin page
312
  function on_show_page() {
313
- //we need the global screen column value to beable to have a sidebar in WordPress 2.8
314
  global $screen_layout_columns;
315
  //add a 3rd content box now for demonstration purpose, boxes added at start of page rendering can't be switched on/off,
316
  //may be needed to ensure that a special box is always available
@@ -319,23 +314,23 @@ class transposh_plugin {
319
  //$data = array('My Data 1', 'My Data 2', 'Available Data 1');
320
  ?>
321
  <div id="transposh-general" class="wrap">
322
- <?php screen_icon('options-general'); ?>
323
  <h2>Transposh</h2>
324
  <form action="admin-post.php" method="post">
325
- <?php wp_nonce_field(TR_NONCE); ?>
326
- <?php wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false ); ?>
327
- <?php wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false ); ?>
328
  <input type="hidden" name="action" value="save_transposh" />
329
 
330
  <div id="poststuff" class="metabox-holder<?php echo 2 == $screen_layout_columns ? ' has-right-sidebar' : ''; ?>">
331
  <div id="side-info-column" class="inner-sidebar">
332
- <?php do_meta_boxes($this->pagehook, 'side', $data); ?>
333
  </div>
334
  <div id="post-body" class="has-sidebar">
335
  <div id="post-body-content" class="has-sidebar-content">
336
- <?php do_meta_boxes($this->pagehook, 'normal', $data);
337
  /* Maybe add static content here later */
338
- //do_meta_boxes($this->pagehook, 'additional', $data); ?>
339
  <p>
340
  <input type="submit" value="Save Changes" class="button-primary" name="Submit"/>
341
  </p>
@@ -357,14 +352,14 @@ class transposh_plugin {
357
  //]]>
358
  </script>
359
 
360
- <?php
361
  }
362
 
363
  //executed if the post arrives initiated by pressing the submit button of form
364
  function on_save_changes() {
365
- //user permission check
366
  if ( !current_user_can('manage_options') )
367
- wp_die( __('Problems?') );
368
  //cross check the given referer
369
  check_admin_referer(TR_NONCE);
370
 
@@ -418,8 +413,14 @@ class transposh_plugin {
418
 
419
  }
420
  function on_contentbox_generic_content($data) {
 
421
  echo '<h4>Rewrite URLs</h4>';
422
  insert_permalink_rewrite_option();
 
 
 
 
 
423
  }
424
  function on_contentbox_community_content($data) {
425
  echo "<p>This space is reserved for the coming community features of Transposh that will help you find translators to help with your site.</p>";
29
  /*
30
  * Insert supported languages section in admin page
31
  */
32
+ function insert_supported_langs() {
 
33
  global $languages, $tr_plugin_url;
34
 
35
  echo
36
  '<script type="text/javascript">'.
37
  'function chbx_change(lang)'.
38
  '{'.
39
+ 'jQuery("#"+lang+"_edit").attr("checked",jQuery("#"+lang+"_view").attr("checked"))'.
40
  '}'.
41
  'jQuery(document).ready(function() {'.
42
+ 'jQuery("#tr_anon").click(function() {'.
43
+ 'if (jQuery("#tr_anon").attr("checked")) {'.
44
+ 'jQuery(".tr_editable").css("display","none");'.
45
+ '} else {'.
46
+ 'jQuery(".tr_editable").css("display","");'.
47
+ '}'.
48
+ '});'.
49
  '});'.
50
+ '</script>';
51
  echo '<table class="'.NO_TRANSLATE_CLASS.'" style="width: 100%"><tr>';
52
 
53
  // we will hide the translatable column if anonymous can translate anyway
57
  for($hdr=0; $hdr < $columns; $hdr++) {
58
  $extrapad = ($hdr != $columns - 1) ? ";padding-right: 40px" : '';
59
  echo '<th style="text-align:left; width:'.(100/$columns).'%">Language</th>'.
60
+ '<th title="Is this language user selectable?">Viewable</th>'.
61
+ '<th title="Is this language visible for translators?"'.$extrastyle.' class="tr_editable">Translatable</th>'.
62
+ '<th>Default</th>'.
63
+ '<th style="text-align:left;width: 80px'.$extrapad.'" title="Can we auto-translate this language?">Auto?</th>';
64
  }
65
  echo '</tr>';
66
 
67
+ foreach($languages as $code => $lang) {
 
68
  list ($language,$flag,$autot) = explode (",",$lang);
69
  if(!($i % $columns)) echo '<tr>';
70
  $i++;
71
 
72
  echo "<td><img src=\"$tr_plugin_url/img/flags/$flag.png\" alt=\"\"/>&nbsp;$language</td>";
73
  echo '<td align="center"><input type="checkbox" id="' . $code .'_view" name="' .
74
+ $code . '_view" onchange="chbx_change(\'' . $code . '\')" ' . is_viewable($code) . '/></td>';
75
  echo '<td class="tr_editable"'.$extrastyle.' align="center"><input type="checkbox" id="' . $code . '_edit" name="' .
76
+ $code . '_edit" ' . is_editable($code). '/></td>';
77
  echo "<td align=\"center\"><input type=\"radio\" name=\"default_lang\" value=\"$code\" " .
78
+ is_default_lang($code). "/></td>";
79
  // TODO: Add icons?
80
  echo "<td>".($autot ? "Y" : "N")."</td>";
81
 
90
  * Determine if the given language code is currentlly editable
91
  * Return 'checked' if true otherwise ""
92
  */
93
+ function is_editable($code) {
 
94
  $langs = get_option(EDITABLE_LANGS);
95
  return (strpos($langs, $code) !== FALSE) ? 'checked="checked"' : '';
96
  }
99
  * Determine if the given language code is currentlly viewable
100
  * Return 'checked' if true otherwise ""
101
  */
102
+ function is_viewable($code) {
 
103
  $langs = get_option(VIEWABLE_LANGS);
104
  return (strpos($langs, $code) !== FALSE) ? 'checked="checked"' : '';
105
  }
108
  * Determine if the given language code is currentlly the default language
109
  * Return 'checked' if true otherwise ""
110
  */
111
+ function is_default_lang($code) {
 
112
  global $languages;
113
  $default = get_option(DEFAULT_LANG);
114
  if(!$languages[$default]) $default = "en";
118
  /*
119
  * Insert permissions section in the admin page
120
  */
121
+ function insert_permissions() {
 
122
  global $wp_roles;
123
  //display known roles and their permission to translate
124
+ foreach($wp_roles->get_names() as $role_name => $something) {
 
125
  echo '<input type="checkbox" value="1" name="'.$role_name.'" '.can_translate($role_name).
126
+ '/> '.ucfirst($role_name).'&nbsp;&nbsp;&nbsp;';
127
  }
128
  //Add our own custom role
129
  echo '<input id="tr_anon" type="checkbox" value="1" name="anonymous" '. can_translate('anonymous') . '/> Anonymous';
133
  * Insert the option to enable/disable rewrite of perlmalinks.
134
  * When disabled only parameters will be used to identify the current language.
135
  */
136
+ function insert_permalink_rewrite_option() {
 
137
  $checked = (get_option(ENABLE_PERMALINKS_REWRITE)) ? 'checked="checked"' :'';
138
  echo '<input type="checkbox" value="1" name="enable_permalinks" '. $checked . '/> '.
139
+ 'Rewrite URLs to be search engine friendly, '.
140
+ 'e.g. (http://wordpress.org/<strong>en</strong>). '.
141
+ 'Requires that permalinks will be enabled.';
142
+ }
143
+
144
+ /*
145
+ * Insert the option to enable/disable pushing of scripts to footer.
146
+ */
147
+ function insert_script_footer_option() {
148
+ $checked = (get_option(ENABLE_FOOTER_SCRIPTS)) ? 'checked="checked"' :'';
149
+ echo '<input type="checkbox" value="1" name="enable_footer_scripts" '. $checked . '/> '.
150
+ 'Push transposh scripts to footer of page instead of header, makes pages load faster. '.
151
+ 'Requires that your theme should have proper footer support.';
152
  }
153
 
154
  /*
155
  * Insert the option to enable/disable automatic translation.
156
  * Enabled by default.
157
  */
158
+ function insert_auto_translate_option() {
 
159
  $checked = (get_option(ENABLE_AUTO_TRANSLATE,1)) ? 'checked="checked"' : '';
160
  echo '<input type="checkbox" value="1" name="enable_autotranslate" '.$checked.'/> '.
161
+ 'Allow automatic translation of pages (currently using Google Translate)';
162
  }
163
 
164
  /*
165
  * Insert the option to enable/disable default language translation.
166
  * Disabled by default.
167
  */
168
+ function insert_default_translate_option() {
 
169
  $checked = (get_option(ENABLE_DEFAULT_TRANSLATE,0)) ? 'checked="checked"' : '';
170
  echo '<input type="checkbox" value="1" name="enable_defaulttranslate" '.$checked.'/> '.
171
+ 'Allow translation of default language - useful for sites with more than one major language';
172
  }
173
  //
174
  /*
175
  * Indicates whether the given role can translate.
176
  * Return either "checked" or ""
177
  */
178
+ function can_translate($role_name) {
 
179
  global $wp_roles;
180
+ if($role_name != 'anonymous') {
 
181
  $role = $wp_roles->get_role($role_name);
182
  if(isset($role) && $role->has_cap(TRANSLATOR))
183
+ return 'checked="checked"';
184
 
185
  }
186
  else
187
+ return (get_option(ANONYMOUS_TRANSLATION,1)) ? 'checked="checked"' : '';
188
  }
189
  //
190
  /*
191
  * Handle newly posted admin options.
192
  */
193
+ function update_admin_options() {
 
194
 
195
  global $wp_roles, $languages;
196
  $viewable_langs = array();
197
  $editable_langs = array();
198
 
199
  //update roles and capabilities
200
+ foreach($wp_roles->get_names() as $role_name => $something) {
 
201
  $role = $wp_roles->get_role($role_name);
202
  if($_POST[$role_name] == "1")
203
+ $role->add_cap(TRANSLATOR);
204
  else
205
+ $role->remove_cap(TRANSLATOR);
206
  }
207
 
208
  //Anonymous needs to be handled differently as it does not have a role
209
  update_option(ANONYMOUS_TRANSLATION, ($_POST['anonymous']) ? 1 : 0);
210
 
211
  //Update the list of supported/editable languages
212
+ foreach($languages as $code => $lang) {
213
+ if($_POST[$code . '_view']) {
 
 
214
  $viewable_langs[$code] = $code;
215
  // force that every viewable lang is editable
216
  $editable_langs[$code] = $code;
217
  }
218
 
219
+ if($_POST[$code . '_edit']) {
 
220
  $editable_langs[$code] = $code;
221
  }
222
  }
225
  update_option(EDITABLE_LANGS, implode(',', $editable_langs));
226
  update_option(DEFAULT_LANG, $_POST['default_lang']);
227
 
228
+ if(get_option(ENABLE_PERMALINKS_REWRITE) != $_POST['enable_permalinks']) {
 
229
  global $wp_rewrite;
230
  update_option(ENABLE_PERMALINKS_REWRITE, $_POST['enable_permalinks']);
231
 
234
  $wp_rewrite->flush_rules();
235
  }
236
 
237
+ if(get_option(ENABLE_FOOTER_SCRIPTS) != $_POST['enable_footer_scripts'])
238
+ update_option(ENABLE_FOOTER_SCRIPTS, $_POST['enable_footer_scripts']);
239
+
240
  if(get_option(ENABLE_AUTO_TRANSLATE,1) != $_POST['enable_autotranslate'])
241
+ update_option(ENABLE_AUTO_TRANSLATE, $_POST['enable_autotranslate']);
242
 
243
  if(get_option(ENABLE_DEFAULT_TRANSLATE) != $_POST['enable_defaulttranslate'])
244
+ update_option(ENABLE_DEFAULT_TRANSLATE, $_POST['enable_defaulttranslate']);
245
 
246
  }
247
 
248
  //class that reperesent the complete plugin
249
  class transposh_plugin {
250
 
251
+ //constructor of class, PHP4 compatible construction for backward compatibility
252
  function transposh_plugin() {
253
+ //add filter for WordPress 2.8 changed backend box system !
254
  add_filter('screen_layout_columns', array(&$this, 'on_screen_layout_columns'), 10, 2);
255
  //add some help
256
  add_filter('contextual_help_list', array(&$this, 'on_contextual_help'),100,2);
272
  function on_contextual_help($filterVal,$screen) {
273
  if($screen == "settings_page_transposh") {
274
  $filterVal["settings_page_transposh"] = '<p>Transposh makes your blog translatable</p>'.
275
+ '<a href="http://transposh.org/">Plugin homepage</a><br/>'.
276
+ '<a href="http://transposh.org/faq/">Frequently asked questions</a>';
277
  }
278
  return $filterVal;
279
  }
280
 
281
  //extend the admin menu
282
  function on_admin_menu() {
283
+ //add our own option page, you can also add it to different sections or use your own one
284
  $this->pagehook = add_options_page('Transposh control center', "Transposh", 'manage_options', TRANSPOSH_ADMIN_PAGE_NAME, array(&$this, 'on_show_page'));
285
  //register callback gets call prior your own page gets rendered
286
  add_action('load-'.$this->pagehook, array(&$this, 'on_load_page'));
288
 
289
  //will be executed if wordpress core detects this page has to be rendered
290
  function on_load_page() {
291
+ //ensure, that the needed javascripts been loaded to allow drag/drop, expand/collapse and hide/show of boxes
292
  wp_enqueue_script('common');
293
  wp_enqueue_script('wp-lists');
294
  wp_enqueue_script('postbox');
305
 
306
  //executed to show the plugins complete admin page
307
  function on_show_page() {
308
+ //we need the global screen column value to beable to have a sidebar in WordPress 2.8
309
  global $screen_layout_columns;
310
  //add a 3rd content box now for demonstration purpose, boxes added at start of page rendering can't be switched on/off,
311
  //may be needed to ensure that a special box is always available
314
  //$data = array('My Data 1', 'My Data 2', 'Available Data 1');
315
  ?>
316
  <div id="transposh-general" class="wrap">
317
+ <?php screen_icon('options-general'); ?>
318
  <h2>Transposh</h2>
319
  <form action="admin-post.php" method="post">
320
+ <?php wp_nonce_field(TR_NONCE); ?>
321
+ <?php wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false ); ?>
322
+ <?php wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false ); ?>
323
  <input type="hidden" name="action" value="save_transposh" />
324
 
325
  <div id="poststuff" class="metabox-holder<?php echo 2 == $screen_layout_columns ? ' has-right-sidebar' : ''; ?>">
326
  <div id="side-info-column" class="inner-sidebar">
327
+ <?php do_meta_boxes($this->pagehook, 'side', $data); ?>
328
  </div>
329
  <div id="post-body" class="has-sidebar">
330
  <div id="post-body-content" class="has-sidebar-content">
331
+ <?php do_meta_boxes($this->pagehook, 'normal', $data);
332
  /* Maybe add static content here later */
333
+ //do_meta_boxes($this->pagehook, 'additional', $data); ?>
334
  <p>
335
  <input type="submit" value="Save Changes" class="button-primary" name="Submit"/>
336
  </p>
352
  //]]>
353
  </script>
354
 
355
+ <?php
356
  }
357
 
358
  //executed if the post arrives initiated by pressing the submit button of form
359
  function on_save_changes() {
360
+ //user permission check
361
  if ( !current_user_can('manage_options') )
362
+ wp_die( __('Problems?') );
363
  //cross check the given referer
364
  check_admin_referer(TR_NONCE);
365
 
413
 
414
  }
415
  function on_contentbox_generic_content($data) {
416
+ global $wp_version;
417
  echo '<h4>Rewrite URLs</h4>';
418
  insert_permalink_rewrite_option();
419
+
420
+ if (floatval($wp_version) >= 2.8) {
421
+ echo '<h4>Add scripts to footer</h4>';
422
+ insert_script_footer_option();
423
+ }
424
  }
425
  function on_contentbox_community_content($data) {
426
  echo "<p>This space is reserved for the coming community features of Transposh that will help you find translators to help with your site.</p>";
transposh_db.php CHANGED
@@ -46,302 +46,286 @@ define("TRANSPOSH_DB_VERSION", "transposh_db_version");
46
  * Returns An array that contains the translated string and it source.
47
  * Will return NULL if no translation is available.
48
  */
49
- function fetch_translation($original, $lang)
50
- {
51
- global $wpdb;
52
- $translated = NULL;
53
-
54
-
55
- //The original is saved in db in its escaped form
56
- $original = $wpdb->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
57
-
58
- if(ENABLE_APC && function_exists('apc_fetch'))
59
- {
60
- $cached = apc_fetch($original .'___'. $lang, $rc);
61
- if($rc === TRUE)
62
- {
63
-
64
- return $cached;
65
- }
66
- }
67
-
68
- $table_name = $wpdb->prefix . TRANSLATIONS_TABLE;
69
- $query = "SELECT * FROM $table_name WHERE original = '$original' and lang = '$lang' ";
70
- $row = $wpdb->get_row($query);
71
-
72
- if($row !== FALSE)
73
- {
74
- $translated_text = stripslashes($row->translated);
75
- $translated = array($translated_text, $row->source);
76
-
77
-
78
- }
79
-
80
- if(ENABLE_APC && function_exists('apc_store'))
81
- {
82
- //If we don't have translation still we want to have it in cache
83
- $cache_entry = $translated;
84
- if($cache_entry == NULL)
85
- {
86
- $cache_entry = "";
87
- }
88
-
89
- //update cache
90
- $rc = apc_store($original .'___'. $lang, $cache_entry, 3600);
91
- if($rc === TRUE)
92
- {
93
-
94
- }
95
- }
96
-
97
-
98
- return $translated;
99
  }
100
 
101
  /*
102
  * A new translation has been posted, update the translation database.
103
  */
104
- function update_translation()
105
- {
106
- global $wpdb;
107
-
108
- $ref=getenv('HTTP_REFERER');
109
- $original = base64_url_decode($_POST['token']);
110
- $translation = $_POST['translation'];
111
- $lang = $_POST['lang'];
112
- $source = $_POST['source'];
113
-
114
- // check params
115
-
116
- if(!isset($original) || !isset($translation) || !isset($lang))
117
- {
118
-
119
- return;
120
- }
121
-
122
- //Check permissions, first the lanugage must be on the edit list. Then either the user
123
- //is a translator or automatic translation if it is enabled.
124
- if(!(is_editable_lang($lang) &&
125
- (is_translator() || ($source == 1 && get_option(ENABLE_AUTO_TRANSLATE, 1)))))
126
- {
127
-
128
- header("HTTP/1.0 401 Unauthorized translation");
129
- exit;
130
- }
131
-
132
- $table_name = $wpdb->prefix . TRANSLATIONS_TABLE;
133
-
134
- //Decode & remove already escaped character to avoid double escaping
135
- $translation = $wpdb->escape(htmlspecialchars(stripslashes(urldecode($translation))));
136
-
137
- //The original content is encoded as base64 before it is sent (i.e. token), after we
138
- //decode it should just the same after it was parsed.
139
- $original = $wpdb->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
140
-
141
- //add our own custom header - so we will know that we got here
142
- header("Transposh: ver-0.2.3 db_version-". DB_VERSION);
143
-
144
- list($translated_text, $old_source) = fetch_translation($original, $lang);
145
- if ($translated_text) {
146
- if ($source == 1) {
147
-
148
- return;
149
- }
150
- if ($translation == $wpdb->escape(htmlspecialchars(stripslashes(urldecode($translated_text)))) && $old_source == $source) {
151
-
152
- return;
153
- }
154
- }
155
-
156
- $update = "REPLACE INTO $table_name (original, translated, lang, source)
157
  VALUES ('" . $original . "','" . $translation . "','" . $lang . "','" . $source . "')";
158
 
159
- $result = $wpdb->query($update);
160
 
161
- if($result !== FALSE)
162
- {
163
- update_transaction_log($original, $translation, $lang, $source);
164
 
165
- //Delete entry from cache
166
- if(ENABLE_APC && function_exists('apc_store'))
167
- {
168
- apc_delete($original .'___'. $lang);
169
- }
170
 
171
-
172
- }
173
- else
174
- {
175
-
176
- header("HTTP/1.0 404 Failed to update language database ".mysql_error());
177
- }
178
 
179
- exit;
180
  }
181
 
182
  /*
183
  * Update the transaction log
184
  */
185
- function update_transaction_log(&$original, &$translation, &$lang, $source)
186
- {
187
- global $wpdb, $user_ID;
188
- get_currentuserinfo();
189
-
190
- // log either the user ID or his IP
191
- if ('' == $user_ID)
192
- {
193
- $loguser = $_SERVER['REMOTE_ADDR'];
194
- }
195
- else
196
- {
197
- $loguser = $user_ID;
198
- }
199
-
200
- $log = "INSERT INTO ".$wpdb->prefix.TRANSLATIONS_LOG." (original, translated, lang, translated_by, source) ".
201
- "VALUES ('" . $original . "','" . $translation . "','" . $lang . "','".$loguser."','".$source."')";
202
-
203
- $result = $wpdb->query($log);
204
-
205
- if($result === FALSE)
206
- {
207
-
208
-
209
- }
210
  }
211
 
212
  /*
213
  * A new translation has been posted, update the translation database.
214
  */
215
- function get_translation_history($token, $lang)
216
- {
217
- global $wpdb;
218
-
219
- $ref=getenv('HTTP_REFERER');
220
- $original = base64_url_decode($token);
221
-
222
- // check params
223
-
224
- if(!isset($original) || !isset($lang))
225
- {
226
-
227
- return;
228
- }
229
-
230
- //Check permissions, first the lanugage must be on the edit list. Then either the user
231
- //is a translator or automatic translation if it is enabled.
232
- if(!(is_editable_lang($lang) && is_translator()))
233
- {
234
-
235
- header("HTTP/1.0 401 Unauthorized history");
236
- exit;
237
- }
238
-
239
- $table_name = $wpdb->prefix . TRANSLATIONS_LOG;
240
-
241
- //The original content is encoded as base64 before it is sent (i.e. token), after we
242
- //decode it should just the same after it was parsed.
243
- $original = $wpdb->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
244
-
245
- //add our own custom header - so we will know that we got here
246
- header("Transposh: ver-0.2.3 db_version-". DB_VERSION);
247
-
248
- $query = "SELECT translated, translated_by, timestamp, source, user_login ".
249
- "FROM $table_name ".
250
- "LEFT JOIN {$wpdb->prefix}users ON translated_by = wp_users.id ".
251
- "WHERE original='$original' AND lang='$lang' ".
252
- "ORDER BY timestamp DESC";
253
- //echo $query;
254
- $rows = $wpdb->get_results($query);
255
-
256
- if($rows !== FALSE)
257
- {
258
- echo '<table>' .
259
- '<thead>'.
260
- '<tr>'.
261
- '<th>Translated</th><th/><th>By</th><th>At</th>'.
262
- '</tr>'.
263
- '</thead>'.
264
- '<tbody>';
265
- foreach ($rows as $row) {
 
 
266
  if (is_null($row->user_login)) $row->user_login = $row->translated_by;
267
- echo "<tr><td>{$row->translated}</td><td source=\"{$row->source}\"/><td user_id=\"{$row->translated_by}\">{$row->user_login}</td><td>{$row->timestamp}</td></tr>";
268
  }
269
- echo '</tbody></table>';
270
- }
271
 
272
- exit;
273
  }
274
 
275
  /*
276
  * Setup the translation database.
277
  */
278
- function setup_db()
279
- {
280
-
281
- global $wpdb;
282
- require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
283
 
284
- $installed_ver = get_option(TRANSPOSH_DB_VERSION);
285
 
286
- if( $installed_ver != DB_VERSION ) {
287
- $table_name = $wpdb->prefix . TRANSLATIONS_TABLE;
288
 
289
-
290
- $sql = "CREATE TABLE $table_name (original VARCHAR(255) NOT NULL,".
291
- "lang CHAR(5) NOT NULL,".
292
- "translated VARCHAR(255),".
293
- "source TINYINT NOT NULL,".
294
- "PRIMARY KEY (original, lang)) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci";
295
 
296
- dbDelta($sql);
297
 
298
 
299
- $table_name = $wpdb->prefix . TRANSLATIONS_LOG;
300
 
301
-
302
- $sql = "CREATE TABLE $table_name (original VARCHAR(255) NOT NULL,".
303
- "lang CHAR(5) NOT NULL,".
304
- "translated VARCHAR(255),".
305
- "translated_by VARCHAR(15),".
306
- "source TINYINT NOT NULL,".
307
- "timestamp TIMESTAMP,".
308
- "PRIMARY KEY (original, lang, timestamp)) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci";
309
 
310
- dbDelta($sql);
311
- update_option(TRANSPOSH_DB_VERSION, DB_VERSION);
312
- }
313
 
314
-
315
  }
316
 
317
  function db_stats () {
318
- global $wpdb;
319
  echo "<h4>Database stats</h4>";
320
- $table_name = $wpdb->prefix . TRANSLATIONS_TABLE;
321
- $log_table_name = $wpdb->prefix . TRANSLATIONS_LOG;
322
  $query = "SELECT count(*) as count FROM `$table_name`";
323
- $rows = $wpdb->get_results($query);
324
- foreach ($rows as $row) {
325
  if ($row->count)
326
- echo "<p>Total of <strong style=\"color:red\">{$row->count}</strong> translated phrases.</p>";
327
  }
328
 
329
  $query = "SELECT count(*) as count,lang FROM `$table_name` WHERE source='0' GROUP BY `lang` ORDER BY `count` DESC LIMIT 3";
330
- $rows = $wpdb->get_results($query);
331
- foreach ($rows as $row) {
332
  if ($row->count)
333
- echo "<p><strong>{$row->lang}</strong> has <strong style=\"color:red\">{$row->count}</strong> human translated phrases.</p>";
334
  }
335
 
336
  echo "<h4>Recent activity</h4>";
337
- $query = "SELECT * FROM `wp_translations_log` WHERE source='0' ORDER BY `timestamp` DESC LIMIT 3";
338
- $rows = $wpdb->get_results($query);
339
- foreach ($rows as $row) {
340
  $td = mysql2date(get_option('date_format').' '.get_option('time_format'), $row->timestamp);
341
  //the_date();
342
  echo "<p>On <strong>{$td}</strong><br/>user <strong>{$row->translated_by}</strong> translated<br/>".
343
- "\"<strong>{$row->original}</strong>\"<br/>to ".
344
- "<strong style=\"color:red\">{$row->lang}</strong><br/>\"<strong>{$row->translated}</strong>\"</p>";
345
  }
346
  }
347
  ?>
46
  * Returns An array that contains the translated string and it source.
47
  * Will return NULL if no translation is available.
48
  */
49
+ function fetch_translation($original, $lang) {
50
+ global $wpdb;
51
+ $translated = NULL;
52
+
53
+
54
+ //The original is saved in db in its escaped form
55
+ $original = $wpdb->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
56
+
57
+ if(ENABLE_APC && function_exists('apc_fetch')) {
58
+ $cached = apc_fetch($original .'___'. $lang, $rc);
59
+ if($rc === TRUE) {
60
+
61
+ return $cached;
62
+ }
63
+ }
64
+
65
+ $table_name = $wpdb->prefix . TRANSLATIONS_TABLE;
66
+ $query = "SELECT * FROM $table_name WHERE original = '$original' and lang = '$lang' ";
67
+ $row = $wpdb->get_row($query);
68
+
69
+ if($row !== FALSE) {
70
+ $translated_text = stripslashes($row->translated);
71
+ $translated = array($translated_text, $row->source);
72
+
73
+
74
+ }
75
+
76
+ if(ENABLE_APC && function_exists('apc_store')) {
77
+ //If we don't have translation still we want to have it in cache
78
+ $cache_entry = $translated;
79
+ if($cache_entry == NULL) {
80
+ $cache_entry = "";
81
+ }
82
+
83
+ //update cache
84
+ $rc = apc_store($original .'___'. $lang, $cache_entry, 3600);
85
+ if($rc === TRUE) {
86
+
87
+ }
88
+ }
89
+
90
+
91
+ return $translated;
 
 
 
 
 
 
 
92
  }
93
 
94
  /*
95
  * A new translation has been posted, update the translation database.
96
  */
97
+ function update_translation() {
98
+ global $wpdb;
99
+
100
+ $ref=getenv('HTTP_REFERER');
101
+ $original = base64_url_decode($_POST['token']);
102
+ $translation = $_POST['translation'];
103
+ $lang = $_POST['lang'];
104
+ $source = $_POST['source'];
105
+
106
+ // check params
107
+
108
+ if(!isset($original) || !isset($translation) || !isset($lang)) {
109
+
110
+ return;
111
+ }
112
+
113
+ //Check permissions, first the lanugage must be on the edit list. Then either the user
114
+ //is a translator or automatic translation if it is enabled.
115
+ if(!(is_editable_lang($lang) &&
116
+ (is_translator() || ($source == 1 && get_option(ENABLE_AUTO_TRANSLATE, 1))))) {
117
+
118
+ header("HTTP/1.0 401 Unauthorized translation");
119
+ exit;
120
+ }
121
+
122
+ $table_name = $wpdb->prefix . TRANSLATIONS_TABLE;
123
+
124
+ //Decode & remove already escaped character to avoid double escaping
125
+ $translation = $wpdb->escape(htmlspecialchars(stripslashes(urldecode($translation))));
126
+
127
+ //The original content is encoded as base64 before it is sent (i.e. token), after we
128
+ //decode it should just the same after it was parsed.
129
+ $original = $wpdb->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
130
+
131
+ //add our own custom header - so we will know that we got here
132
+ header("Transposh: ver-0.2.4 db_version-". DB_VERSION);
133
+
134
+ list($translated_text, $old_source) = fetch_translation($original, $lang);
135
+ if ($translated_text) {
136
+ if ($source == 1) {
137
+
138
+ return;
139
+ }
140
+ if ($translation == $wpdb->escape(htmlspecialchars(stripslashes(urldecode($translated_text)))) && $old_source == $source) {
141
+
142
+ return;
143
+ }
144
+ }
145
+
146
+ $update = "REPLACE INTO $table_name (original, translated, lang, source)
 
 
 
147
  VALUES ('" . $original . "','" . $translation . "','" . $lang . "','" . $source . "')";
148
 
149
+ $result = $wpdb->query($update);
150
 
151
+ if($result !== FALSE) {
152
+ update_transaction_log($original, $translation, $lang, $source);
 
153
 
154
+ //Delete entry from cache
155
+ if(ENABLE_APC && function_exists('apc_store')) {
156
+ apc_delete($original .'___'. $lang);
157
+ }
 
158
 
159
+
160
+ }
161
+ else {
162
+
163
+ header("HTTP/1.0 404 Failed to update language database ".mysql_error());
164
+ }
 
165
 
166
+ exit;
167
  }
168
 
169
  /*
170
  * Update the transaction log
171
  */
172
+ function update_transaction_log(&$original, &$translation, &$lang, $source) {
173
+ global $wpdb, $user_ID;
174
+ get_currentuserinfo();
175
+
176
+ // log either the user ID or his IP
177
+ if ('' == $user_ID) {
178
+ $loguser = $_SERVER['REMOTE_ADDR'];
179
+ }
180
+ else {
181
+ $loguser = $user_ID;
182
+ }
183
+
184
+ $log = "INSERT INTO ".$wpdb->prefix.TRANSLATIONS_LOG." (original, translated, lang, translated_by, source) ".
185
+ "VALUES ('" . $original . "','" . $translation . "','" . $lang . "','".$loguser."','".$source."')";
186
+
187
+ $result = $wpdb->query($log);
188
+
189
+ if($result === FALSE) {
190
+
191
+
192
+ }
 
 
 
 
193
  }
194
 
195
  /*
196
  * A new translation has been posted, update the translation database.
197
  */
198
+ function get_translation_history($token, $lang) {
199
+ global $wpdb;
200
+
201
+ $ref=getenv('HTTP_REFERER');
202
+ $original = base64_url_decode($token);
203
+
204
+
205
+ // check params
206
+
207
+ if(!isset($original) || !isset($lang)) {
208
+
209
+ return;
210
+ }
211
+
212
+
213
+ //Check permissions, first the lanugage must be on the edit list. Then either the user
214
+ //is a translator or automatic translation if it is enabled.
215
+ if(!(is_editable_lang($lang) && is_translator())) {
216
+
217
+ header("HTTP/1.0 401 Unauthorized history");
218
+ exit;
219
+ }
220
+
221
+
222
+ $table_name = $wpdb->prefix . TRANSLATIONS_LOG;
223
+
224
+
225
+ //The original content is encoded as base64 before it is sent (i.e. token), after we
226
+ //decode it should just the same after it was parsed.
227
+ $original = $wpdb->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
228
+
229
+ //add our own custom header - so we will know that we got here
230
+ header("Transposh: ver-0.2.4 db_version-". DB_VERSION);
231
+
232
+ $query = "SELECT translated, translated_by, timestamp, source, user_login ".
233
+ "FROM $table_name ".
234
+ "LEFT JOIN {$wpdb->prefix}users ON translated_by = {$wpdb->prefix}users.id ".
235
+ "WHERE original='$original' AND lang='$lang' ".
236
+ "ORDER BY timestamp DESC";
237
+
238
+
239
+ $rows = $wpdb->get_results($query);
240
+ // trying
241
+
242
+ if($rows !== FALSE) {
243
+ echo '<table>' .
244
+ '<thead>'.
245
+ '<tr>'.
246
+ '<th>Translated</th><th/><th>By</th><th>At</th>'.
247
+ '</tr>'.
248
+ '</thead>'.
249
+ '<tbody>';
250
+ foreach ($rows as $row) {
251
  if (is_null($row->user_login)) $row->user_login = $row->translated_by;
252
+ echo "<tr><td>{$row->translated}</td><td source=\"{$row->source}\"/><td user_id=\"{$row->translated_by}\">{$row->user_login}</td><td>{$row->timestamp}</td></tr>";
253
  }
254
+ echo '</tbody></table>';
255
+ }
256
 
257
+ exit;
258
  }
259
 
260
  /*
261
  * Setup the translation database.
262
  */
263
+ function setup_db() {
264
+
265
+ global $wpdb;
266
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
 
267
 
268
+ $installed_ver = get_option(TRANSPOSH_DB_VERSION);
269
 
270
+ if( $installed_ver != DB_VERSION ) {
271
+ $table_name = $wpdb->prefix . TRANSLATIONS_TABLE;
272
 
273
+
274
+ $sql = "CREATE TABLE $table_name (original VARCHAR(255) NOT NULL,".
275
+ "lang CHAR(5) NOT NULL,".
276
+ "translated VARCHAR(255),".
277
+ "source TINYINT NOT NULL,".
278
+ "PRIMARY KEY (original, lang)) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci";
279
 
280
+ dbDelta($sql);
281
 
282
 
283
+ $table_name = $wpdb->prefix . TRANSLATIONS_LOG;
284
 
285
+
286
+ $sql = "CREATE TABLE $table_name (original VARCHAR(255) NOT NULL,".
287
+ "lang CHAR(5) NOT NULL,".
288
+ "translated VARCHAR(255),".
289
+ "translated_by VARCHAR(15),".
290
+ "source TINYINT NOT NULL,".
291
+ "timestamp TIMESTAMP,".
292
+ "PRIMARY KEY (original, lang, timestamp)) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci";
293
 
294
+ dbDelta($sql);
295
+ update_option(TRANSPOSH_DB_VERSION, DB_VERSION);
296
+ }
297
 
298
+
299
  }
300
 
301
  function db_stats () {
302
+ global $wpdb;
303
  echo "<h4>Database stats</h4>";
304
+ $table_name = $wpdb->prefix . TRANSLATIONS_TABLE;
305
+ $log_table_name = $wpdb->prefix . TRANSLATIONS_LOG;
306
  $query = "SELECT count(*) as count FROM `$table_name`";
307
+ $rows = $wpdb->get_results($query);
308
+ foreach ($rows as $row) {
309
  if ($row->count)
310
+ echo "<p>Total of <strong style=\"color:red\">{$row->count}</strong> translated phrases.</p>";
311
  }
312
 
313
  $query = "SELECT count(*) as count,lang FROM `$table_name` WHERE source='0' GROUP BY `lang` ORDER BY `count` DESC LIMIT 3";
314
+ $rows = $wpdb->get_results($query);
315
+ foreach ($rows as $row) {
316
  if ($row->count)
317
+ echo "<p><strong>{$row->lang}</strong> has <strong style=\"color:red\">{$row->count}</strong> human translated phrases.</p>";
318
  }
319
 
320
  echo "<h4>Recent activity</h4>";
321
+ $query = "SELECT * FROM `$log_table_name` WHERE source='0' ORDER BY `timestamp` DESC LIMIT 3";
322
+ $rows = $wpdb->get_results($query);
323
+ foreach ($rows as $row) {
324
  $td = mysql2date(get_option('date_format').' '.get_option('time_format'), $row->timestamp);
325
  //the_date();
326
  echo "<p>On <strong>{$td}</strong><br/>user <strong>{$row->translated_by}</strong> translated<br/>".
327
+ "\"<strong>{$row->original}</strong>\"<br/>to ".
328
+ "<strong style=\"color:red\">{$row->lang}</strong><br/>\"<strong>{$row->translated}</strong>\"</p>";
329
  }
330
  }
331
  ?>
transposh_widget.php CHANGED
@@ -28,117 +28,107 @@ require_once("transposh.php");
28
  * Intercept init calls to see if it was posted by the widget.
29
  *
30
  */
31
- function init_transposh()
32
- {
33
- if ($_POST['transposh_widget_posted'])
34
- {
35
-
36
 
37
- $ref=getenv('HTTP_REFERER');
38
- $lang = $_POST[LANG_PARAM];
39
 
40
  //remove existing language settings.
41
  $ref = cleanup_url($ref);
42
 
43
- if($lang != "none")
44
- {
45
- $is_edit = $_POST[EDIT_PARAM];
46
- $ref = rewrite_url_lang_param($ref, $lang, $is_edit);
47
 
48
- //ref is generated with html entities encoded, needs to be
49
- //decoded when used in the http header (i.e. 302 redirect)
50
- $ref = html_entity_decode($ref, ENT_NOQUOTES);
51
- }
52
 
53
-
54
 
55
- wp_redirect($ref);
56
- exit;
57
- }
58
  }
59
 
60
  /*
61
  * Register the widget.
62
  */
63
- function transposh_widget_init()
64
- {
65
-
66
- if (!function_exists('register_sidebar_widget'))
67
- {
68
- return;
69
- }
70
-
71
- // Register widget
72
- register_sidebar_widget(array('Transposh', 'widgets'), 'transposh_widget');
73
-
74
- // Register widget control
75
- register_widget_control("Transposh",'transposh_widget_control');
76
-
77
- //regigster callback for widget's css
78
- add_action('wp_print_styles', 'add_transposh_widget_css');
79
  }
80
 
81
  /*
82
  * Add custom css, i.e. transposh.css
83
  */
84
  function add_transposh_widget_css() {
85
- global $tr_plugin_url;
86
-
87
- //include the transposh_widget.css
88
- wp_enqueue_style("transposh_widget","$tr_plugin_url/css/transposh_widget.css",array(),'0.2.3');
89
-
90
  }
91
 
92
  /*
93
  * The actual widget implementation.
94
  */
95
- function transposh_widget($args)
96
- {
97
-
98
- global $languages, $wp_query, $tr_plugin_url,$lang;
99
- extract($args);
100
-
101
- $page_url = ($_SERVER['HTTPS'] == 'on' ?
102
- 'https://' : 'http://') . $_SERVER["SERVER_NAME"];
103
- $page_url .= ($_SERVER["SERVER_PORT"] != "80" ? ":" .$_SERVER["SERVER_PORT"] : "");
104
- $page_url .= $_SERVER["REQUEST_URI"];
105
-
106
- $is_edit = ($wp_query->query_vars[EDIT_PARAM] == "1" ? TRUE : FALSE);
107
- $lang = $wp_query->query_vars[LANG_PARAM];
108
- if (get_option(ENABLE_DEFAULT_TRANSLATE) && !$lang) $lang = get_default_lang();
109
-
110
- $options = get_option(WIDGET_TRANSPOSH);
111
- $viewable_langs = get_option(VIEWABLE_LANGS);
112
- $editable_langs = get_option(EDITABLE_LANGS);
113
- $is_translator = is_translator();
114
 
115
  $is_showing_languages = FALSE;
116
  //TODO: improve this shortening
117
  $plugpath = parse_url($tr_plugin_url, PHP_URL_PATH);
118
 
119
- echo $before_widget . $before_title . __("Translation") . $after_title;
120
 
121
- switch ($options['style']) {
122
- case 1: // flags
123
- //keep the flags in the same direction regardless of the overall page direction
124
  echo "<div class=\"" . NO_TRANSLATE_CLASS . " transposh_flags\" >";
125
 
126
- foreach($languages as $code => $lang2)
127
- {
128
- list($language,$flag) = explode (",",$lang2);
129
 
130
  //remove any language identifier
 
131
  $page_url = cleanup_url($page_url);
 
132
 
133
- //Only show languages which are viewable or (editable and the user is a translator)
134
- if(strpos($viewable_langs, $code) !== FALSE ||
135
- ($is_translator && strpos($editable_langs, $code) !== FALSE) ||
136
- (get_option(DEFAULT_LANG) == $code && $lang))
137
- {
138
- $page_url2 = rewrite_url_lang_param($page_url, $code, $is_edit);
139
- if (get_option(DEFAULT_LANG) == $code) {
140
- $page_url2 = $page_url;
141
- }
142
  //TODO: improve this hacky! shortening
143
  $urlpath = parse_url($page_url2, PHP_URL_PATH);
144
  if (trim(parse_url($page_url2, PHP_URL_QUERY)) != '')
@@ -146,38 +136,35 @@ function transposh_widget($args)
146
  if (trim(parse_url($page_url2, PHP_URL_FRAGMENT)) != '')
147
  $urlpath .= '#'.parse_url($page_url2, PHP_URL_FRAGMENT);
148
 
149
- echo "<a href=\"" . $urlpath . "\">".
150
- "<img src=\"$plugpath/img/flags/$flag.png\" title=\"$language\" alt=\"$language\"".
151
- " style=\"padding: 1px 3px;border: 0px\"/></a>";
 
152
  $is_showing_languages = TRUE;
153
- }
154
- }
155
  echo "</div>";
156
 
157
- // this is the form for the edit...
158
- echo "<form action=\"$page_url\" method=\"post\">";
159
- echo "<input type=\"hidden\" name=\"lang\" id=\"lang\" value=\"$lang\"/>";
160
- break;
161
- case 2: // language list
162
- //keep the flags in the same direction regardless of the overall page direction
163
  echo "<div class=\"" . NO_TRANSLATE_CLASS . " transposh_flags\" >";
164
 
165
- foreach($languages as $code => $lang2)
166
- {
167
- list($language,$flag) = explode (",",$lang2);
168
 
169
  //remove any language identifier
170
  $page_url = cleanup_url($page_url);
171
 
172
- //Only show languages which are viewable or (editable and the user is a translator)
173
- if(strpos($viewable_langs, $code) !== FALSE ||
174
- ($is_translator && strpos($editable_langs, $code) !== FALSE) ||
175
- (get_option(DEFAULT_LANG) == $code && $lang))
176
- {
177
- $page_url2 = rewrite_url_lang_param($page_url, $code, $is_edit);
178
- if (get_option(DEFAULT_LANG) == $code) {
179
- $page_url2 = $page_url;
180
- }
181
  //TODO: improve this hacky! shortening
182
  $urlpath = parse_url($page_url2, PHP_URL_PATH);
183
  if (trim(parse_url($page_url2, PHP_URL_QUERY)) != '')
@@ -185,66 +172,60 @@ function transposh_widget($args)
185
  if (trim(parse_url($page_url2, PHP_URL_FRAGMENT)) != '')
186
  $urlpath .= '#'.parse_url($page_url2, PHP_URL_FRAGMENT);
187
 
188
- echo "<a href=\"" . $urlpath . "\">".
189
- "<img src=\"$plugpath/img/flags/$flag.png\" title=\"$language\" alt=\"$language\"".
190
- " style=\"padding: 1px 3px;border: 0px\"/></a>$language<br/>";
 
191
  $is_showing_languages = TRUE;
192
- }
193
- }
194
  echo "</div>";
195
 
196
- // this is the form for the edit...
197
- echo "<form action=\"$page_url\" method=\"post\">";
198
- echo "<input type=\"hidden\" name=\"lang\" id=\"lang\" value=\"$lang\"/>";
199
- break;
200
- default: // language selection
201
 
202
  echo "<form action=\"$page_url\" method=\"post\">";
203
  echo "<span class=\"" .NO_TRANSLATE_CLASS . "\" >";
204
- echo "<select name=\"lang\" id=\"lang\" onchange=\"Javascript:this.form.submit();\">";
205
- echo "<option value=\"none\">[Language]</option>";
206
 
207
- foreach($languages as $code => $lang2)
208
- {
209
- list($language,$flag) = explode (",",$lang2);
210
 
211
  //Only show languages which are viewable or (editable and the user is a translator)
212
- if(strpos($viewable_langs, $code) !== FALSE ||
213
- ($is_translator && strpos($editable_langs, $code) !== FALSE) ||
214
- (get_option(DEFAULT_LANG) == $code && $lang))
215
- {
216
- $is_selected = ($lang == $code ? "selected=\"selected\"" : "" );
217
- echo "<option value=\"$code\" $is_selected>" . $language . "</option>";
218
  $is_showing_languages = TRUE;
219
- }
220
- }
221
- echo "</select><br/>";
222
  echo "</span>"; // the no_translate for the language list
223
- }
224
 
225
 
226
  //at least one language showing - add the edit box if applicable
227
- if($is_showing_languages)
228
- {
229
- //Add the edit checkbox only for translators on languages marked as editable
230
- if($is_translator && strpos($editable_langs, $lang) !== FALSE)
231
- {
232
  echo "<input type=\"checkbox\" name=\"" . EDIT_PARAM . "\" value=\"1\" " .
233
- ($is_edit ? "checked=\"checked\"" : "") .
234
  " onclick=\"this.form.submit();\"/>&nbsp;Edit Translation";
235
  }
236
 
237
  echo "<input type=\"hidden\" name=\"transposh_widget_posted\" value=\"1\"/>";
238
  }
239
- else
240
- {
241
- //no languages configured - error message
242
- echo '<p> No languages available for display. Check the Transposh settings (Admin).</p>';
243
  }
244
 
245
  echo "</form>";
246
  //echo "<button onClick=\"do_auto_translate();\">translate all</button>";
247
- echo "<div id=\"".SPAN_PREFIX."credit\">by <a href=\"http://transposh.org\"><img class=\"".NO_TRANSLATE_CLASS."\" src=\"$plugpath/img/tplogo.png\" style=\"padding:1px;border:0px\" title=\"Transposh\" alt=\"Transposh\"/></a></div>";
248
  echo $after_widget;
249
  }
250
 
@@ -252,17 +233,15 @@ function transposh_widget($args)
252
  * Remove from url any language (or editing) params that were added for our use.
253
  * Return the scrubed url
254
  */
255
- function cleanup_url($url)
256
- {
257
  global $home_url, $home_url_quoted;
258
 
259
  //cleanup previous lang & edit parameter from url
260
  $url = preg_replace("/(" . LANG_PARAM . "|" . EDIT_PARAM . ")=[^&]*/i", "", $url);
261
 
262
 
263
- if(!$home_url)
264
- {
265
- //make sure required home urls are fetched - as they are need now
266
  init_global_vars();
267
  }
268
 
@@ -271,7 +250,7 @@ function cleanup_url($url)
271
 
272
  //some more cleans
273
  $url = preg_replace("/&$/", "", $url);
274
- $url = preg_replace("/\?$/", "", $url);
275
 
276
  return $url;
277
  }
@@ -280,40 +259,37 @@ function cleanup_url($url)
280
  * Mark the given text so it will not subject to translation.
281
  * Return the text with the required tags
282
  */
283
- function no_translate($text)
284
- {
285
- return "<span class=\"" . NO_TRANSLATE_CLASS . "\">$text</span>";
286
  }
287
 
288
- function transposh_widget_post()
289
- {
290
- $options = $newoptions = get_option(WIDGET_TRANSPOSH);
291
- $newoptions['style'] = $_POST['transposh-style'];
292
  $newoptions['progressbar'] = ($_POST['transposh-progress']) ? 1 : 0;
293
 
294
- if ($options != $newoptions) update_option(WIDGET_TRANSPOSH, $newoptions);
295
 
296
  }
297
 
298
  /*
299
  * This is the widget control, allowing the selection of presentation type.
300
  */
301
- function transposh_widget_control()
302
- {
303
- if (isset($_POST['transposh-submit'])) transposh_widget_post();
304
- $options = get_option(WIDGET_TRANSPOSH);
305
 
306
  echo '<p><label for="transposh-style">Style:<br />'.
307
- '<select id="transposh-style" name="transposh-style">'.
308
- '<option value="0"' . ($options['style'] == 0 ? ' selected="selected"' : '').'>Language selection</option>'.
309
- '<option value="1"' . ($options['style'] == 1 ? ' selected="selected"' : '').'>Flags</option>'.
310
- '<option value="2"' . ($options['style'] == 2 ? ' selected="selected"' : '').'>Language list</option>'.
311
- '</select>'.
312
- '</label></p>'.
313
- '<p><label for="transposh-progress">Effects:<br/>'.
314
- '<input type="checkbox" id="transposh-progress" name="transposh-progress"'.($options['progressbar'] ? ' checked="checked"' : '').'/>'.
315
- '&nbsp;Show progress bar</label></p>'.
316
- '<input type="hidden" name="transposh-submit" id="transposh-submit" value="1"/>';
317
  }
318
 
319
  //Register callback for WordPress events
28
  * Intercept init calls to see if it was posted by the widget.
29
  *
30
  */
31
+ function init_transposh() {
32
+ if (isset ($_POST['transposh_widget_posted'])) {
33
+
 
 
34
 
35
+ $ref=getenv('HTTP_REFERER');
36
+ $lang = $_POST[LANG_PARAM];
37
 
38
  //remove existing language settings.
39
  $ref = cleanup_url($ref);
40
 
41
+ if($lang != "none") {
42
+ $ref = rewrite_url_lang_param($ref, $lang, $_POST[EDIT_PARAM]);
 
 
43
 
44
+ //ref is generated with html entities encoded, needs to be
45
+ //decoded when used in the http header (i.e. 302 redirect)
46
+ $ref = html_entity_decode($ref, ENT_NOQUOTES);
47
+ }
48
 
49
+
50
 
51
+ wp_redirect($ref);
52
+ exit;
53
+ }
54
  }
55
 
56
  /*
57
  * Register the widget.
58
  */
59
+ function transposh_widget_init() {
60
+
61
+ if (!function_exists('register_sidebar_widget')) {
62
+ return;
63
+ }
64
+
65
+ // Register widget
66
+ register_sidebar_widget(array('Transposh', 'widgets'), 'transposh_widget');
67
+
68
+ // Register widget control
69
+ register_widget_control("Transposh",'transposh_widget_control');
70
+
71
+ //regigster callback for widget's css
72
+ add_action('wp_print_styles', 'add_transposh_widget_css');
 
 
73
  }
74
 
75
  /*
76
  * Add custom css, i.e. transposh.css
77
  */
78
  function add_transposh_widget_css() {
79
+ global $tr_plugin_url;
80
+
81
+ //include the transposh_widget.css
82
+ wp_enqueue_style("transposh_widget","$tr_plugin_url/css/transposh_widget.css",array(),'0.2.4');
83
+
84
  }
85
 
86
  /*
87
  * The actual widget implementation.
88
  */
89
+ function transposh_widget($args) {
90
+
91
+ global $languages, $wp_query, $tr_plugin_url;
92
+ extract($args);
93
+
94
+ //$page_url = "http://";
95
+ $page_url = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://') ;
96
+ $page_url .= $_SERVER["SERVER_NAME"];
97
+ $page_url .= ($_SERVER["SERVER_PORT"] != "80" ? ":" .$_SERVER["SERVER_PORT"] : "");
98
+ $page_url .= $_SERVER["REQUEST_URI"];
99
+
100
+
101
+ $options = get_option(WIDGET_TRANSPOSH);
102
+ $viewable_langs = get_option(VIEWABLE_LANGS);
103
+ $editable_langs = get_option(EDITABLE_LANGS);
104
+ $is_translator = is_translator();
 
 
 
105
 
106
  $is_showing_languages = FALSE;
107
  //TODO: improve this shortening
108
  $plugpath = parse_url($tr_plugin_url, PHP_URL_PATH);
109
 
110
+ echo $before_widget . $before_title . __("Translation") . $after_title;
111
 
112
+ switch ($options['style']) {
113
+ case 1: // flags
114
+ //keep the flags in the same direction regardless of the overall page direction
115
  echo "<div class=\"" . NO_TRANSLATE_CLASS . " transposh_flags\" >";
116
 
117
+ foreach($languages as $code => $lang2) {
118
+ list($language,$flag) = explode (",",$lang2);
 
119
 
120
  //remove any language identifier
121
+
122
  $page_url = cleanup_url($page_url);
123
+
124
 
125
+ //Only show languages which are viewable or (editable and the user is a translator)
126
+ if(strpos($viewable_langs, $code) !== FALSE || is_editable_lang($code) || (get_option(DEFAULT_LANG) == $code)) {
127
+
128
+ $page_url2 = rewrite_url_lang_param($page_url, $code, $GLOBALS['is_edit_mode']);
129
+ if (get_option(DEFAULT_LANG) == $code) {
130
+ $page_url2 = $page_url;
131
+ }
 
 
132
  //TODO: improve this hacky! shortening
133
  $urlpath = parse_url($page_url2, PHP_URL_PATH);
134
  if (trim(parse_url($page_url2, PHP_URL_QUERY)) != '')
136
  if (trim(parse_url($page_url2, PHP_URL_FRAGMENT)) != '')
137
  $urlpath .= '#'.parse_url($page_url2, PHP_URL_FRAGMENT);
138
 
139
+
140
+ echo "<a href=\"" . $urlpath . "\">".
141
+ "<img src=\"$plugpath/img/flags/$flag.png\" title=\"$language\" alt=\"$language\"".
142
+ " style=\"padding: 1px 3px;border: 0px\"/></a>";
143
  $is_showing_languages = TRUE;
144
+ }
145
+ }
146
  echo "</div>";
147
 
148
+ // this is the form for the edit...
149
+ echo "<form action=\"$page_url\" method=\"post\">";
150
+ echo "<input type=\"hidden\" name=\"lang\" id=\"lang\" value=\"{$GLOBALS['lang']}\"/>";
151
+ break;
152
+ case 2: // language list
153
+ //keep the flags in the same direction regardless of the overall page direction
154
  echo "<div class=\"" . NO_TRANSLATE_CLASS . " transposh_flags\" >";
155
 
156
+ foreach($languages as $code => $lang2) {
157
+ list($language,$flag) = explode (",",$lang2);
 
158
 
159
  //remove any language identifier
160
  $page_url = cleanup_url($page_url);
161
 
162
+ //Only show languages which are viewable or (editable and the user is a translator)
163
+ if(strpos($viewable_langs, $code) !== FALSE || is_editable_lang($code) || (get_option(DEFAULT_LANG) == $code)) {
164
+ $page_url2 = rewrite_url_lang_param($page_url, $code, $GLOBALS['is_edit_mode']);
165
+ if (get_option(DEFAULT_LANG) == $code) {
166
+ $page_url2 = $page_url;
167
+ }
 
 
 
168
  //TODO: improve this hacky! shortening
169
  $urlpath = parse_url($page_url2, PHP_URL_PATH);
170
  if (trim(parse_url($page_url2, PHP_URL_QUERY)) != '')
172
  if (trim(parse_url($page_url2, PHP_URL_FRAGMENT)) != '')
173
  $urlpath .= '#'.parse_url($page_url2, PHP_URL_FRAGMENT);
174
 
175
+
176
+ echo "<a href=\"" . $urlpath . "\">".
177
+ "<img src=\"$plugpath/img/flags/$flag.png\" title=\"$language\" alt=\"$language\"".
178
+ " style=\"padding: 1px 3px;border: 0px\"/></a>$language<br/>";
179
  $is_showing_languages = TRUE;
180
+ }
181
+ }
182
  echo "</div>";
183
 
184
+ // this is the form for the edit...
185
+ echo "<form action=\"$page_url\" method=\"post\">";
186
+ echo "<input type=\"hidden\" name=\"lang\" id=\"lang\" value=\"{$GLOBALS['lang']}\"/>";
187
+ break;
188
+ default: // language selection
189
 
190
  echo "<form action=\"$page_url\" method=\"post\">";
191
  echo "<span class=\"" .NO_TRANSLATE_CLASS . "\" >";
192
+ echo "<select name=\"lang\" id=\"lang\" onchange=\"Javascript:this.form.submit();\">";
193
+ echo "<option value=\"none\">[Language]</option>";
194
 
195
+ foreach($languages as $code => $lang2) {
196
+ list($language,$flag) = explode (",",$lang2);
 
197
 
198
  //Only show languages which are viewable or (editable and the user is a translator)
199
+ if(strpos($viewable_langs, $code) !== FALSE || is_editable_lang($code) || (get_option(DEFAULT_LANG) == $code)) {
200
+ $is_selected = ($GLOBALS['lang'] == $code ? "selected=\"selected\"" : "" );
201
+ echo "<option value=\"$code\" $is_selected>" . $language . "</option>";
 
 
 
202
  $is_showing_languages = TRUE;
203
+ }
204
+ }
205
+ echo "</select><br/>";
206
  echo "</span>"; // the no_translate for the language list
207
+ }
208
 
209
 
210
  //at least one language showing - add the edit box if applicable
211
+ if($is_showing_languages) {
212
+ //Add the edit checkbox only for translators on languages marked as editable
213
+ if(is_editing_permitted()) {
 
 
214
  echo "<input type=\"checkbox\" name=\"" . EDIT_PARAM . "\" value=\"1\" " .
215
+ ($GLOBALS['is_edit_mode'] ? "checked=\"checked\"" : "") .
216
  " onclick=\"this.form.submit();\"/>&nbsp;Edit Translation";
217
  }
218
 
219
  echo "<input type=\"hidden\" name=\"transposh_widget_posted\" value=\"1\"/>";
220
  }
221
+ else {
222
+ //no languages configured - error message
223
+ echo '<p>No languages available for display. Check the Transposh settings (Admin).</p>';
 
224
  }
225
 
226
  echo "</form>";
227
  //echo "<button onClick=\"do_auto_translate();\">translate all</button>";
228
+ echo "<div id=\"".SPAN_PREFIX."credit\">by <a href=\"http://transposh.org\"><img class=\"".NO_TRANSLATE_CLASS."\" src=\"$plugpath/img/tplogo.png\" style=\"padding:1px;border:0px\" title=\"Transposh\" alt=\"Transposh\"/></a></div>";
229
  echo $after_widget;
230
  }
231
 
233
  * Remove from url any language (or editing) params that were added for our use.
234
  * Return the scrubed url
235
  */
236
+ function cleanup_url($url) {
 
237
  global $home_url, $home_url_quoted;
238
 
239
  //cleanup previous lang & edit parameter from url
240
  $url = preg_replace("/(" . LANG_PARAM . "|" . EDIT_PARAM . ")=[^&]*/i", "", $url);
241
 
242
 
243
+ if(!$home_url) {
244
+ //make sure required home urls are fetched - as they are need now
 
245
  init_global_vars();
246
  }
247
 
250
 
251
  //some more cleans
252
  $url = preg_replace("/&$/", "", $url);
253
+ $url = preg_replace("/\?$/", "", $url);
254
 
255
  return $url;
256
  }
259
  * Mark the given text so it will not subject to translation.
260
  * Return the text with the required tags
261
  */
262
+ function no_translate($text) {
263
+ return "<span class=\"" . NO_TRANSLATE_CLASS . "\">$text</span>";
 
264
  }
265
 
266
+ function transposh_widget_post() {
267
+ $options = $newoptions = get_option(WIDGET_TRANSPOSH);
268
+ $newoptions['style'] = $_POST['transposh-style'];
 
269
  $newoptions['progressbar'] = ($_POST['transposh-progress']) ? 1 : 0;
270
 
271
+ if ($options != $newoptions) update_option(WIDGET_TRANSPOSH, $newoptions);
272
 
273
  }
274
 
275
  /*
276
  * This is the widget control, allowing the selection of presentation type.
277
  */
278
+ function transposh_widget_control() {
279
+ if (isset($_POST['transposh-submit'])) transposh_widget_post();
280
+ $options = get_option(WIDGET_TRANSPOSH);
 
281
 
282
  echo '<p><label for="transposh-style">Style:<br />'.
283
+ '<select id="transposh-style" name="transposh-style">'.
284
+ '<option value="0"' . ($options['style'] == 0 ? ' selected="selected"' : '').'>Language selection</option>'.
285
+ '<option value="1"' . ($options['style'] == 1 ? ' selected="selected"' : '').'>Flags</option>'.
286
+ '<option value="2"' . ($options['style'] == 2 ? ' selected="selected"' : '').'>Language list</option>'.
287
+ '</select>'.
288
+ '</label></p>'.
289
+ '<p><label for="transposh-progress">Effects:<br/>'.
290
+ '<input type="checkbox" id="transposh-progress" name="transposh-progress"'.($options['progressbar'] ? ' checked="checked"' : '').'/>'.
291
+ '&nbsp;Show progress bar</label></p>'.
292
+ '<input type="hidden" name="transposh-submit" id="transposh-submit" value="1"/>';
293
  }
294
 
295
  //Register callback for WordPress events