Index: trunk/extensions/Translate/TranslateEditAddons.php |
— | — | @@ -148,89 +148,6 @@ |
149 | 149 | return true; |
150 | 150 | } |
151 | 151 | |
152 | | - private static function getFallbacks( $code ) { |
153 | | - global $wgUser, $wgTranslateLanguageFallbacks; |
154 | | - |
155 | | - $preference = $wgUser->getOption( 'translate-editlangs' ); |
156 | | - if ( $preference !== 'default' ) { |
157 | | - $fallbacks = array_map( 'trim', explode( ',', $preference ) ); |
158 | | - foreach ( $fallbacks as $k => $v ) if ( $v === $code ) unset( $fallbacks[$k] ); |
159 | | - return $fallbacks; |
160 | | - } |
161 | | - |
162 | | - $fallbacks = array(); |
163 | | - if ( isset( $wgTranslateLanguageFallbacks[$code] ) ) { |
164 | | - $temp = $wgTranslateLanguageFallbacks[$code]; |
165 | | - if ( !is_array( $temp ) ) { |
166 | | - $fallbacks = array( $temp ); |
167 | | - } else { |
168 | | - $fallbacks = $temp; |
169 | | - } |
170 | | - } |
171 | | - |
172 | | - $realFallback = $code ? Language::getFallbackFor( $code ) : 'en'; |
173 | | - if ( $realFallback && $realFallback !== 'en' ) { |
174 | | - $fallbacks = array_merge( array( $realFallback ), $fallbacks ); |
175 | | - } |
176 | | - |
177 | | - return $fallbacks; |
178 | | - } |
179 | | - |
180 | | - private static function doBox( $msg, $code, $title = false, $makelink = false, $group = false ) { |
181 | | - global $wgUser, $wgLang; |
182 | | - if ( $msg === null ) { return ''; } |
183 | | - |
184 | | - $name = TranslateUtils::getLanguageName( $code, false, $wgLang->getCode() ); |
185 | | - $code = strtolower( $code ); |
186 | | - |
187 | | - $attributes = array(); |
188 | | - if ( !$title ) { |
189 | | - $attributes['class'] = 'mw-sp-translate-in-other-big'; |
190 | | - } elseif ( $code === 'en' ) { |
191 | | - $attributes['class'] = 'mw-sp-translate-edit-definition'; |
192 | | - } else { |
193 | | - $attributes['class'] = 'mw-sp-translate-edit-committed'; |
194 | | - } |
195 | | - if ( mb_strlen( $msg ) < 100 && !$title ) { |
196 | | - $attributes['class'] = 'mw-sp-translate-in-other-small'; |
197 | | - } |
198 | | - |
199 | | - $msg = TranslateUtils::convertWhiteSpaceToHTML( $msg ); |
200 | | - |
201 | | - if ( !$title ) $title = "$name ($code)"; |
202 | | - $title = htmlspecialchars( $title ); |
203 | | - |
204 | | - if ( $makelink ) { |
205 | | - $skin = $wgUser->getSkin(); |
206 | | - $linkTitle = Title::newFromText( $makelink ); |
207 | | - $title = $skin->link( |
208 | | - $linkTitle, |
209 | | - $title, |
210 | | - array(), |
211 | | - array( 'action' => 'edit' ) |
212 | | - ); |
213 | | - } |
214 | | - |
215 | | - if ( $group && $attributes['class'] == 'mw-sp-translate-edit-definition' ) { |
216 | | - global $wgLang; |
217 | | - |
218 | | - $skin = $wgUser->getSkin(); |
219 | | - $userLang = $wgLang->getCode(); |
220 | | - $groupId = $group->getId(); |
221 | | - $linkTitle = SpecialPage::getTitleFor( 'Translate' ); |
222 | | - $title = $skin->link( |
223 | | - $linkTitle, |
224 | | - $title, |
225 | | - array(), |
226 | | - array( |
227 | | - 'group' => $groupId, |
228 | | - 'language' => $userLang |
229 | | - ) |
230 | | - ); |
231 | | - } |
232 | | - return TranslateUtils::fieldset( $title, Xml::tags( 'code', null, $msg ), $attributes ); |
233 | | - } |
234 | | - |
235 | 152 | /** |
236 | 153 | * @return Array of the message and the language |
237 | 154 | */ |
— | — | @@ -280,193 +197,15 @@ |
281 | 198 | private static function editBoxes( $object ) { |
282 | 199 | global $wgTranslateDocumentationLanguageCode, $wgOut, $wgRequest; |
283 | 200 | |
284 | | - list( $key, $code, $group ) = self::getKeyCodeGroup( $object->mTitle ); |
285 | | - if ( $group === null ) return; |
| 201 | + $th = new TranslationHelpers( $object->mTitle ); |
286 | 202 | |
287 | | - $nsMain = $group->getNamespace(); |
288 | | - |
289 | | - $en = $group->getMessage( $key, 'en' ); |
290 | | - $xx = $group->getMessage( $key, $code ); |
291 | | - |
292 | | - |
293 | | - // Set-up the content area contents properly and not randomly as in |
294 | | - // MediaWiki core. $translation is also used for checks later on. Also |
295 | | - // add the fuzzy string if necessary. |
296 | | - $translation = TranslateUtils::getMessageContent( $key, $code, $nsMain ); |
297 | | - if ( $translation !== null ) { |
298 | | - if ( !self::hasFuzzyString( $translation ) && self::isFuzzy( $object->mTitle ) ) { |
299 | | - $translation = TRANSLATE_FUZZY . $translation; |
300 | | - } |
301 | | - } else { |
302 | | - $translation = $xx; |
303 | | - } |
304 | | - |
305 | 203 | if ( $object->firsttime && !$wgRequest->getCheck( 'oldid' ) && !$wgRequest->getCheck( 'undo' ) ) { |
306 | | - $object->textbox1 = $translation; |
307 | 204 | } else { |
308 | | - $translation = $object->textbox1; |
| 205 | + $th->setTranslation( $object->textbox1 ); |
309 | 206 | } |
310 | 207 | |
311 | | - $boxes = array(); |
312 | | - // In other languages (if any) |
313 | | - $inOtherLanguages = array(); |
314 | | - $namespace = $object->mTitle->getNsText(); |
315 | | - foreach ( self::getFallbacks( $code ) as $fbcode ) { |
316 | | - $fb = TranslateUtils::getMessageContent( $key, $fbcode, $nsMain ); |
317 | | - // Try harder TODO: fixme with the new localisation cache |
318 | | - if ( $fb === null ) $fb = $group->getMessage( $key, $fbcode ); |
319 | | - if ( $fb !== null ) { |
320 | | - /* add a link for editing the fallback messages */ |
321 | | - $inOtherLanguages[] = self::dobox( $fb, $fbcode, false, $namespace . ':' . $key . '/' . $fbcode ); |
322 | | - } |
323 | | - } |
324 | | - if ( count( $inOtherLanguages ) ) { |
325 | | - $boxes[] = TranslateUtils::fieldset( wfMsgHtml( self::MSG . 'in-other-languages' , $key ), |
326 | | - implode( "\n", $inOtherLanguages ), array( 'class' => 'mw-sp-translate-edit-inother' ) ); |
327 | | - } |
328 | | - |
329 | | - global $wgTranslateTM; |
330 | | - if ( $wgTranslateTM !== false ) { |
331 | | - $sugboxes = array(); |
332 | | - |
333 | | - $server = $wgTranslateTM['server']; |
334 | | - $port = $wgTranslateTM['port']; |
335 | | - $timeout = $wgTranslateTM['timeout']; |
336 | | - |
337 | | - $def = rawurlencode( $en ); |
338 | | - $url = "$server:$port/tmserver/en/$code/unit/$def"; |
339 | | - $suggestions = Http::get( $url, $timeout ); |
340 | | - if ( $suggestions !== false ) { |
341 | | - $suggestions = json_decode( $suggestions, true ); |
342 | | - $suggestions = array_slice( $suggestions, 0, 3 ); |
343 | | - foreach ( $suggestions as $s ) { |
344 | | - if ( $s['target'] === $translation ) continue; |
345 | | - $sugboxes[] = TranslateUtils::fieldset( |
346 | | - wfMsgHtml( 'translate-edit-tmsug' , sprintf( '%.2f', $s['quality'] ) ), |
347 | | - TranslateUtils::convertWhiteSpaceToHTML( $s['target'] ), |
348 | | - array( 'class' => 'mw-sp-translate-edit-tmsug', 'title' => $s['source'] ) |
349 | | - ); |
350 | | - } |
351 | | - } |
352 | | - if ( count( $sugboxes ) > 1 ) { |
353 | | - $boxes[] = TranslateUtils::fieldset( wfMsgHtml( 'translate-edit-tmsugs' ), |
354 | | - implode( "\n", $sugboxes ), array( 'class' => 'mw-sp-translate-edit-tmsugs' ) ); |
355 | | - } elseif ( count( $sugboxes ) ) { |
356 | | - $boxes[] = $sugboxes[0]; |
357 | | - } |
358 | | - } |
359 | | - |
360 | | - // Make the non-mandatory boxes a different group, for easy access |
361 | | - $boxes = array( |
362 | | - Xml::tags( 'div', array( 'class' => 'mw-sp-translate-edit-extra' ), implode( "\n\n", $boxes ) ) |
363 | | - ); |
364 | | - |
365 | | - // User provided documentation |
366 | | - if ( $wgTranslateDocumentationLanguageCode ) { |
367 | | - global $wgUser; |
368 | | - $title = Title::makeTitle( $nsMain, $key . '/' . $wgTranslateDocumentationLanguageCode ); |
369 | | - $edit = $wgUser->getSkin()->link( |
370 | | - $title, |
371 | | - wfMsgHtml( self::MSG . 'contribute' ), |
372 | | - array(), |
373 | | - array( 'action' => 'edit' ) |
374 | | - ); |
375 | | - $info = TranslateUtils::getMessageContent( $key, $wgTranslateDocumentationLanguageCode, $nsMain ); |
376 | | - if ( $info === null ) { |
377 | | - $info = $group->getMessage( $key, $wgTranslateDocumentationLanguageCode ); |
378 | | - } |
379 | | - $class = 'mw-sp-translate-edit-info'; |
380 | | - if ( $info === null ) { |
381 | | - $info = wfMsg( self::MSG . 'no-information' ); |
382 | | - $class = 'mw-sp-translate-edit-noinfo'; |
383 | | - } |
384 | | - |
385 | | - if ( $group instanceof GettextMessageGroup ) { |
386 | | - $reader = $group->getReader( 'en' ); |
387 | | - if ( $reader ) { |
388 | | - global $wgContLang; |
389 | | - $mykey = $wgContLang->lcfirst( $key ); |
390 | | - $data = $reader->parseFile(); |
391 | | - $help = GettextFormatWriter::formatcomments( @$data[$mykey]['comments'], false, @$data[$mykey]['flags'] ); |
392 | | - $info .= "<hr /><pre>$help</pre>"; |
393 | | - } |
394 | | - } |
395 | | - |
396 | | - $class .= ' mw-sp-translate-message-documentation'; |
397 | | - |
398 | | - if ( $info ) { |
399 | | - $contents = $wgOut->parse( $info ); |
400 | | - // Remove whatever block element wrapup the parser likes to add |
401 | | - $contents = preg_replace( '~^<([a-z]+)>(.*)</\1>$~us', '\2', $contents ); |
402 | | - $boxes[] = TranslateUtils::fieldset( |
403 | | - wfMsgHtml( self::MSG . 'information', $edit , $key ), $contents, array( 'class' => $class ) |
404 | | - ); |
405 | | - } |
406 | | - } |
407 | | - |
408 | | - global $wgEnablePageTranslation; |
409 | | - if ( $wgEnablePageTranslation && $group instanceof WikiPageMessageGroup ) { |
410 | | - // TODO: encapsulate somewhere |
411 | | - $page = TranslatablePage::newFromTitle( $group->title ); |
412 | | - $rev = $page->getTransRev( "$key/$code" ); |
413 | | - $latest = $page->getMarkedTag(); |
414 | | - if ( $rev !== $latest ) { |
415 | | - $oldpage = TranslatablePage::newFromRevision( $group->title, $rev ); |
416 | | - $oldtext = null; |
417 | | - $newtext = null; |
418 | | - foreach ( $oldpage->getParse()->getSectionsForSave() as $section ) { |
419 | | - if ( $group->title->getPrefixedDBKey() . '/' . $section->id === $key ) { |
420 | | - $oldtext = $section->getTextForTrans(); |
421 | | - } |
422 | | - } |
423 | | - |
424 | | - foreach ( $page->getParse()->getSectionsForSave() as $section ) { |
425 | | - if ( $group->title->getPrefixedDBKey() . '/' . $section->id === $key ) { |
426 | | - $newtext = $section->getTextForTrans(); |
427 | | - } |
428 | | - } |
429 | | - |
430 | | - if ( $oldtext !== $newtext ) { |
431 | | - wfLoadExtensionMessages( 'PageTranslation' ); |
432 | | - $diff = new DifferenceEngine; |
433 | | - $diff->setText( $oldtext, $newtext ); |
434 | | - $diff->setReducedLineNumbers(); |
435 | | - $boxes[] = $diff->getDiff( wfMsgHtml( 'tpt-diff-old' ), wfMsgHtml( 'tpt-diff-new' ) ); |
436 | | - $diff->showDiffStyle(); |
437 | | - } |
438 | | - } |
439 | | - } |
440 | | - |
441 | | - // Definition |
442 | | - if ( $en !== null ) { |
443 | | - $label = " ({$group->getLabel()})"; |
444 | | - $boxes[] = self::doBox( $en, 'en', wfMsg( self::MSG . 'definition' ) . $label, false, $group ); |
445 | | - } |
446 | | - |
447 | | - // Some syntactic checks |
448 | | - if ( $translation !== null && $code !== $wgTranslateDocumentationLanguageCode ) { |
449 | | - $message = new FatMessage( $key, $en ); |
450 | | - // Take the contents from edit field as a translation |
451 | | - $message->setTranslation( $translation ); |
452 | | - $checker = $group->getChecker(); |
453 | | - if ( $checker ) { |
454 | | - $checks = $checker->checkMessage( $message, $code ); |
455 | | - if ( count( $checks ) ) { |
456 | | - $checkMessages = array(); |
457 | | - foreach ( $checks as $checkParams ) { |
458 | | - array_splice( $checkParams, 1, 0, 'parseinline' ); |
459 | | - $checkMessages[] = call_user_func_array( 'wfMsgExt', $checkParams ); |
460 | | - } |
461 | | - |
462 | | - $boxes[] = TranslateUtils::fieldset( |
463 | | - wfMsgHtml( self::MSG . 'warnings' ), implode( '<hr />', $checkMessages ), |
464 | | - array( 'class' => 'mw-sp-translate-edit-warnings' ) ); |
465 | | - } |
466 | | - } |
467 | | - } |
468 | | - |
469 | 208 | TranslateUtils::injectCSS(); |
470 | | - return Xml::tags( 'div', array( 'class' => 'mw-sp-translate-edit-fields' ), implode( "\n\n", $boxes ) ); |
| 209 | + return $th->getBoxes(); |
471 | 210 | } |
472 | 211 | |
473 | 212 | public static function hasFuzzyString( $text ) { |
Index: trunk/extensions/Translate/utils/TranslationHelpers.php |
— | — | @@ -93,6 +93,10 @@ |
94 | 94 | return $translation; |
95 | 95 | } |
96 | 96 | |
| 97 | + public function setTranslation( $translation ) { |
| 98 | + $this->translation = $translation; |
| 99 | + } |
| 100 | + |
97 | 101 | public function getBoxes( $types = null ) { |
98 | 102 | if ( !$this->group ) return ''; |
99 | 103 | |
— | — | @@ -100,6 +104,7 @@ |
101 | 105 | $all = array( |
102 | 106 | 'other-languages' => array( $this, 'getOtherLanguagesBox' ), |
103 | 107 | 'translation-memory' => array( $this, 'getTmBox' ), |
| 108 | + 'page-translation' => array( $this, 'getPageDiff' ), |
104 | 109 | 'separator' => array( $this, 'getSeparatorBox' ), |
105 | 110 | 'documenation' => array( $this, 'getDocumentationBox' ), |
106 | 111 | 'definition' => array( $this, 'getDefinitionBox' ), |
— | — | @@ -116,7 +121,7 @@ |
117 | 122 | if ( count( $boxes ) ) { |
118 | 123 | return Html::rawElement( 'div', array( 'class' => 'mw-sp-translate-edit-fields' ), implode( "\n\n", $boxes ) ); |
119 | 124 | } else { |
120 | | - throw new MWException( "no boxes" ); |
| 125 | + return ''; |
121 | 126 | } |
122 | 127 | } |
123 | 128 | |
— | — | @@ -127,6 +132,7 @@ |
128 | 133 | protected function getTmBox() { |
129 | 134 | global $wgTranslateTM; |
130 | 135 | if ( $wgTranslateTM === false ) return null; |
| 136 | + if ( !$this->targetLanguage ) return null; |
131 | 137 | |
132 | 138 | // Needed data |
133 | 139 | $code = $this->targetLanguage; |
— | — | @@ -148,9 +154,13 @@ |
149 | 155 | $suggestions = array_slice( $suggestions, 0, 3 ); |
150 | 156 | foreach ( $suggestions as $s ) { |
151 | 157 | $label = wfMsgHtml( 'translate-edit-tmmatch' , sprintf( '%.2f', $s['quality'] ) ); |
| 158 | + $source_page = Title::newFromText( $s['context'] . "/$code" ); |
| 159 | + if ( $source_page ) { |
| 160 | + $label = self::editLink( $source_page, |
| 161 | + htmlspecialchars( $label ), array( 'action' => 'edit' ) |
| 162 | + ); |
| 163 | + } |
152 | 164 | $text = TranslateUtils::convertWhiteSpaceToHTML( $s['target'] ); |
153 | | - |
154 | | - $text = TranslateUtils::convertWhiteSpaceToHTML( $text ); |
155 | 165 | $params = array( 'class' => 'mw-sp-translate-edit-tmsug', 'title' => $s['source'] ); |
156 | 166 | $boxes[] = Html::rawElement( 'div', $params, self::legend( $label ) . $text . self::clear() ); |
157 | 167 | } |
— | — | @@ -217,6 +227,7 @@ |
218 | 228 | $checks = $checker->checkMessage( $message, $code ); |
219 | 229 | if ( !count( $checks ) ) return null; |
220 | 230 | |
| 231 | + |
221 | 232 | $checkMessages = array(); |
222 | 233 | foreach ( $checks as $checkParams ) { |
223 | 234 | array_splice( $checkParams, 1, 0, 'parseinline' ); |
— | — | @@ -310,6 +321,44 @@ |
311 | 322 | |
312 | 323 | } |
313 | 324 | |
| 325 | + protected function getPageDiff() { |
| 326 | + global $wgEnablePageTranslation; |
| 327 | + if ( !$wgEnablePageTranslation ) return null; |
| 328 | + if ( !$this->group instanceof WikiPageMessageGroup ) return null; |
| 329 | + |
| 330 | + // Shortcuts |
| 331 | + $code = $this->targetLanguage; |
| 332 | + $key = $this->page; |
| 333 | + |
| 334 | + // TODO: encapsulate somewhere |
| 335 | + $page = TranslatablePage::newFromTitle( $this->group->title ); |
| 336 | + $rev = $page->getTransRev( "$key/$code" ); |
| 337 | + $latest = $page->getMarkedTag(); |
| 338 | + if ( $rev === $latest ) return null; |
| 339 | + |
| 340 | + $oldpage = TranslatablePage::newFromRevision( $this->group->title, $rev ); |
| 341 | + $oldtext = $newtext = null; |
| 342 | + foreach ( $oldpage->getParse()->getSectionsForSave() as $section ) { |
| 343 | + if ( $this->group->title->getPrefixedDBKey() . '/' . $section->id === $key ) { |
| 344 | + $oldtext = $section->getTextForTrans(); |
| 345 | + } |
| 346 | + } |
| 347 | + |
| 348 | + foreach ( $page->getParse()->getSectionsForSave() as $section ) { |
| 349 | + if ( $this->group->title->getPrefixedDBKey() . '/' . $section->id === $key ) { |
| 350 | + $newtext = $section->getTextForTrans(); |
| 351 | + } |
| 352 | + } |
| 353 | + |
| 354 | + if ( $oldtext === $newtext ) return null; |
| 355 | + |
| 356 | + $diff = new DifferenceEngine; |
| 357 | + $diff->setText( $oldtext, $newtext ); |
| 358 | + $diff->setReducedLineNumbers(); |
| 359 | + $diff->showDiffStyle(); |
| 360 | + return $diff->getDiff( wfMsgHtml( 'tpt-diff-old' ), wfMsgHtml( 'tpt-diff-new' ) ); |
| 361 | + } |
| 362 | + |
314 | 363 | protected static function legend( $label ) { |
315 | 364 | return Html::rawElement( 'div', array( 'class' => 'mw-translate-legend' ), $label ); |
316 | 365 | } |