00001 <?php
00014 class TranslateUtils {
00023 public static function title( $message, $code, $ns = NS_MEDIAWIKI ) {
00024
00025 static $cache = array();
00026 $key = $ns . ':' . $message;
00027
00028 if ( !isset( $cache[$key] ) ) {
00029 $cache[$key] = Title::capitalize( $message, $ns );
00030 }
00031
00032 if ( $code ) {
00033 return $cache[$key] . '/' . $code;
00034 } else {
00035 return $cache[$key];
00036 }
00037 }
00038
00045 public static function figureMessage( $text ) {
00046 $pos = strrpos( $text, '/' );
00047 $code = substr( $text, $pos + 1 );
00048 $key = substr( $text, 0, $pos );
00049
00050 return array( $key, $code );
00051 }
00052
00060 public static function getMessageContent( $key, $language, $namespace = NS_MEDIAWIKI ) {
00061 $title = self::title( $key, $language, $namespace );
00062 $data = self::getContents( array( $title ), $namespace );
00063
00064 return isset( $data[$title][0] ) ? $data[$title][0] : null;
00065 }
00066
00075 public static function getContents( $titles, $namespace ) {
00076 $dbr = wfGetDB( DB_SLAVE );
00077 $rows = $dbr->select( array( 'page', 'revision', 'text' ),
00078 array( 'page_title', 'old_text', 'old_flags', 'rev_user_text' ),
00079 array(
00080 'page_namespace' => $namespace,
00081 'page_latest=rev_id',
00082 'rev_text_id=old_id',
00083 'page_title' => $titles
00084 ),
00085 __METHOD__
00086 );
00087
00088 $titles = array();
00089 foreach ( $rows as $row ) {
00090 $titles[$row->page_title] = array(
00091 Revision::getRevisionText( $row ),
00092 $row->rev_user_text
00093 );
00094 }
00095 $rows->free();
00096
00097 return $titles;
00098 }
00099
00108 public static function translationChanges( $hours = 24, $bots = false, $ns = null ) {
00109 global $wgTranslateMessageNamespaces;
00110
00111 $dbr = wfGetDB( DB_SLAVE );
00112 $recentchanges = $dbr->tableName( 'recentchanges' );
00113 $hours = intval( $hours );
00114 $cutoff_unixtime = time() - ( $hours * 3600 );
00115 $cutoff = $dbr->timestamp( $cutoff_unixtime );
00116
00117 $namespaces = $dbr->makeList( $wgTranslateMessageNamespaces );
00118 if ( $ns ) {
00119 $namespaces = $dbr->makeList( $ns );
00120 }
00121
00122 $fields = 'rc_title, rc_timestamp, rc_user_text, rc_namespace';
00123
00124
00125 $sql = "SELECT $fields, substring_index(rc_title, '/', -1) as lang FROM $recentchanges " .
00126 "WHERE rc_timestamp >= '{$cutoff}' " .
00127 ( $bots ? '' : 'AND rc_bot = 0 ' ) .
00128 "AND rc_namespace in ($namespaces) " .
00129 "ORDER BY lang ASC, rc_timestamp DESC";
00130
00131 $res = $dbr->query( $sql, __METHOD__ );
00132 $rows = iterator_to_array( $res );
00133
00134 return $rows;
00135 }
00136
00137
00138
00145 public static function getLanguageName( $code, $language = 'en' ) {
00146 $languages = TranslateUtils::getLanguageNames( $language );
00147
00148 if ( isset( $languages[$code] ) ) {
00149 return $languages[$code];
00150 } else {
00151 return $code;
00152 }
00153 }
00154
00161 public static function languageSelector( $language, $selectedId ) {
00162 $selector = self::getLanguageSelector( $language );
00163 $selector->setDefault( $selectedId );
00164 $selector->setAttribute( 'id', 'language' );
00165 $selector->setAttribute( 'name', 'language' );
00166
00167 return $selector->getHtml();
00168 }
00169
00176 public static function getLanguageSelector( $language, $labelOption = false ) {
00177 $languages = self::getLanguageNames( $language );
00178 ksort( $languages );
00179
00180 $selector = new XmlSelect();
00181 if ( $labelOption !== false ) {
00182 $selector->addOption( $labelOption, '-' );
00183 }
00184
00185 foreach ( $languages as $code => $name ) {
00186 $selector->addOption( "$code - $name", $code );
00187 }
00188
00189 return $selector;
00190 }
00191
00199 public static function getLanguageNames( $code ) {
00200 if ( is_callable( array( 'Language', 'fetchLanguageNames' ) ) ) {
00201 $languageNames = Language::fetchLanguageNames( $code, 'mw' );
00202 } elseif ( is_callable( array( 'LanguageNames', 'getNames' ) ) ) {
00203 $languageNames = LanguageNames::getNames( $code,
00204 LanguageNames::FALLBACK_NORMAL,
00205 LanguageNames::LIST_MW
00206 );
00207 } else {
00208 $languageNames = Language::getLanguageNames( false );
00209 }
00210
00211
00212 global $wgDummyLanguageCodes;
00213
00214 foreach ( array_keys( $wgDummyLanguageCodes ) as $dummyLanguageCode ) {
00215 unset( $languageNames[$dummyLanguageCode] );
00216 }
00217
00218 wfRunHooks( 'TranslateSupportedLanguages', array( &$languageNames, $code ) );
00219
00220 return $languageNames;
00221 }
00222
00229 public static function messageKeyToGroup( $namespace, $key ) {
00230 $groups = self::messageKeyToGroups( $namespace, $key );
00231
00232 return count( $groups ) ? $groups[0] : null;
00233 }
00234
00241 public static function messageKeyToGroups( $namespace, $key ) {
00242 $mi = MessageIndex::singleton()->retrieve();
00243 $normkey = self::normaliseKey( $namespace, $key );
00244
00245 if ( isset( $mi[$normkey] ) ) {
00246 return (array)$mi[$normkey];
00247 } else {
00248 return array();
00249 }
00250 }
00251
00258 public static function normaliseKey( $namespace, $key ) {
00259 $key = lcfirst( $key );
00260
00261 return strtr( "$namespace:$key", " ", "_" );
00262 }
00263
00271 public static function fieldset( $legend, $contents, $attributes = array() ) {
00272 return Xml::openElement( 'fieldset', $attributes ) .
00273 Xml::tags( 'legend', null, $legend ) . $contents .
00274 Xml::closeElement( 'fieldset' );
00275 }
00276
00288 public static function convertWhiteSpaceToHTML( $msg ) {
00289 $msg = htmlspecialchars( $msg );
00290 $msg = preg_replace( '/^ /m', ' ', $msg );
00291 $msg = preg_replace( '/ $/m', ' ', $msg );
00292 $msg = preg_replace( '/ /', '  ', $msg );
00293 $msg = str_replace( "\n", '<br />', $msg );
00294
00295 return $msg;
00296 }
00297
00303 public static function assetPath( $path ) {
00304 global $wgExtensionAssetsPath;
00305
00306 return "$wgExtensionAssetsPath/Translate/$path";
00307 }
00308
00315 public static function cacheFile( $filename ) {
00316 global $wgTranslateCacheDirectory, $wgCacheDirectory;
00317
00318 if ( $wgTranslateCacheDirectory !== false ) {
00319 $dir = $wgTranslateCacheDirectory;
00320 } elseif ( $wgCacheDirectory !== false ) {
00321 $dir = $wgCacheDirectory;
00322 } else {
00323 throw new MWException( "\$wgCacheDirectory must be configured" );
00324 }
00325
00326 return "$dir/$filename";
00327 }
00328
00329 public static function groupSelector( $default = false ) {
00330 $groups = MessageGroups::getAllGroups();
00331 $selector = new XmlSelect( 'group', 'group', $default );
00332
00333 foreach ( $groups as $id => $class ) {
00334 if ( MessageGroups::getGroup( $id )->exists() ) {
00335 $selector->addOption( $class->getLabel(), $id );
00336 }
00337 }
00338
00339 return $selector;
00340 }
00341
00349 public static function addSpecialHelpLink( OutputPage $out, $to, $overrideBaseUrl = false ) {
00350 $out->addModules( 'ext.translate.helplink' );
00351 $text = wfMessage( 'translate-gethelp' )->escaped();
00352
00353 if ( $overrideBaseUrl ) {
00354 $helpUrl = $to;
00355 } else {
00356 $helpUrl = "//www.mediawiki.org/wiki/Special:MyLanguage/$to";
00357 }
00358
00359 $link = Html::rawElement(
00360 'a',
00361 array(
00362 'href' => $helpUrl,
00363 'target' => '_blank'
00364 ),
00365 "$text" );
00366 $wrapper = Html::rawElement( 'div', array( 'class' => 'mw-translate-helplink' ), $link );
00367 $out->addHtml( $wrapper );
00368 }
00369
00377 public static function getTokenAction( $token ) {
00378 global $wgVersion;
00379 $method = "action=tokens&type=$token";
00380 if ( version_compare( $wgVersion, '1.20', '<' ) ) {
00381 $method = "action=query&prop=info&intoken=$token&titles=Token";
00382 }
00383
00384 return $method;
00385 }
00386
00392 public static function getPlaceholder() {
00393 static $i = 0;
00394
00395 return "\x7fUNIQ" . dechex( mt_rand( 0, 0x7fffffff ) ) .
00396 dechex( mt_rand( 0, 0x7fffffff ) ) . '-' . $i++;
00397 }
00398
00406 public static function getIcon( MessageGroup $g, $size ) {
00407 $icon = $g->getIcon();
00408 if ( substr( $icon, 0, 7 ) !== 'wiki://' ) {
00409 return null;
00410 }
00411
00412 $formats = array();
00413
00414 $filename = substr( $icon, 7 );
00415 $file = wfFindFile( $filename );
00416 if ( !$file ) {
00417 wfWarn( "Unknown message group icon file $icon" );
00418
00419 return null;
00420 }
00421
00422 if ( $file->isVectorized() ) {
00423 $formats['vector'] = $file->getFullUrl();
00424 }
00425
00426 $formats['raster'] = $file->createThumb( $size, $size );
00427
00428 return $formats;
00429 }
00430
00436 public static function parseLanguageCodes( $codes ) {
00437 $langs = array_map( 'trim', explode( ',', $codes ) );
00438 if ( $langs[0] === '*' ) {
00439 $languages = Language::fetchLanguageNames();
00440 ksort( $languages );
00441 $langs = array_keys( $languages );
00442 }
00443
00444 return $langs;
00445 }
00446 }