r61168 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r61167‎ | r61168 | r61169 >
Date:15:08, 17 January 2010
Author:nikerabbit
Status:ok
Tags:
Comment:
Finish migration to TranslationHelpers.php

This remove lots of code duplication between TranslateEditAddons
and TranslationHelpers by moving missing boxes to TranslationHelpers.
This also removes any differences in boxes between the old and new
editing interface. Most notably the "in other languages" box takes
less space and is prettier.

In addition Translation memory suggestions now take advantage of the
context parameter if it exists. Suggestions now link back to the
message which was used to create the suggestion. Context parameter
is populated by the new tm-export script.

Fixes also a bug in tm suggestions querying invalid url from the
tm server if it was unable to determine language code, for example
when visiting the message page itself instead of subpage.

There is a bug in the translation page box with new js edit
interface. CSS styles for the diffs are not loaded. Possible fix
would by to load the styles always, since there isn't any mechanism
to load styles on demand afterwards.
Modified paths:
  • /trunk/extensions/Translate/TranslateEditAddons.php (modified) (history)
  • /trunk/extensions/Translate/utils/TranslationHelpers.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Translate/TranslateEditAddons.php
@@ -148,89 +148,6 @@
149149 return true;
150150 }
151151
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 -
235152 /**
236153 * @return Array of the message and the language
237154 */
@@ -280,193 +197,15 @@
281198 private static function editBoxes( $object ) {
282199 global $wgTranslateDocumentationLanguageCode, $wgOut, $wgRequest;
283200
284 - list( $key, $code, $group ) = self::getKeyCodeGroup( $object->mTitle );
285 - if ( $group === null ) return;
 201+ $th = new TranslationHelpers( $object->mTitle );
286202
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 -
305203 if ( $object->firsttime && !$wgRequest->getCheck( 'oldid' ) && !$wgRequest->getCheck( 'undo' ) ) {
306 - $object->textbox1 = $translation;
307204 } else {
308 - $translation = $object->textbox1;
 205+ $th->setTranslation( $object->textbox1 );
309206 }
310207
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 -
469208 TranslateUtils::injectCSS();
470 - return Xml::tags( 'div', array( 'class' => 'mw-sp-translate-edit-fields' ), implode( "\n\n", $boxes ) );
 209+ return $th->getBoxes();
471210 }
472211
473212 public static function hasFuzzyString( $text ) {
Index: trunk/extensions/Translate/utils/TranslationHelpers.php
@@ -93,6 +93,10 @@
9494 return $translation;
9595 }
9696
 97+ public function setTranslation( $translation ) {
 98+ $this->translation = $translation;
 99+ }
 100+
97101 public function getBoxes( $types = null ) {
98102 if ( !$this->group ) return '';
99103
@@ -100,6 +104,7 @@
101105 $all = array(
102106 'other-languages' => array( $this, 'getOtherLanguagesBox' ),
103107 'translation-memory' => array( $this, 'getTmBox' ),
 108+ 'page-translation' => array( $this, 'getPageDiff' ),
104109 'separator' => array( $this, 'getSeparatorBox' ),
105110 'documenation' => array( $this, 'getDocumentationBox' ),
106111 'definition' => array( $this, 'getDefinitionBox' ),
@@ -116,7 +121,7 @@
117122 if ( count( $boxes ) ) {
118123 return Html::rawElement( 'div', array( 'class' => 'mw-sp-translate-edit-fields' ), implode( "\n\n", $boxes ) );
119124 } else {
120 - throw new MWException( "no boxes" );
 125+ return '';
121126 }
122127 }
123128
@@ -127,6 +132,7 @@
128133 protected function getTmBox() {
129134 global $wgTranslateTM;
130135 if ( $wgTranslateTM === false ) return null;
 136+ if ( !$this->targetLanguage ) return null;
131137
132138 // Needed data
133139 $code = $this->targetLanguage;
@@ -148,9 +154,13 @@
149155 $suggestions = array_slice( $suggestions, 0, 3 );
150156 foreach ( $suggestions as $s ) {
151157 $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+ }
152164 $text = TranslateUtils::convertWhiteSpaceToHTML( $s['target'] );
153 -
154 - $text = TranslateUtils::convertWhiteSpaceToHTML( $text );
155165 $params = array( 'class' => 'mw-sp-translate-edit-tmsug', 'title' => $s['source'] );
156166 $boxes[] = Html::rawElement( 'div', $params, self::legend( $label ) . $text . self::clear() );
157167 }
@@ -217,6 +227,7 @@
218228 $checks = $checker->checkMessage( $message, $code );
219229 if ( !count( $checks ) ) return null;
220230
 231+
221232 $checkMessages = array();
222233 foreach ( $checks as $checkParams ) {
223234 array_splice( $checkParams, 1, 0, 'parseinline' );
@@ -310,6 +321,44 @@
311322
312323 }
313324
 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+
314363 protected static function legend( $label ) {
315364 return Html::rawElement( 'div', array( 'class' => 'mw-translate-legend' ), $label );
316365 }

Status & tagging log