00001 <?php
00014 class TranslateHooks {
00020 public static function setupNamespaces( &$list ) {
00021 global $wgPageTranslationNamespace;
00022 if ( !defined( 'NS_TRANSLATIONS' ) ) {
00023 define( 'NS_TRANSLATIONS', $wgPageTranslationNamespace );
00024 define( 'NS_TRANSLATIONS_TALK', $wgPageTranslationNamespace + 1 );
00025 }
00026 $list[NS_TRANSLATIONS] = 'Translations';
00027 $list[NS_TRANSLATIONS_TALK] = 'Translations_talk';
00028
00029 return true;
00030 }
00031
00037 public static function setupTranslate() {
00038 global $wgTranslatePHPlot, $wgAutoloadClasses, $wgHooks;
00039
00040 if ( $wgTranslatePHPlot ) {
00041 $wgAutoloadClasses['PHPlot'] = $wgTranslatePHPlot;
00042 }
00043
00044 global $wgReservedUsernames, $wgTranslateFuzzyBotName;
00045 $wgReservedUsernames[] = $wgTranslateFuzzyBotName;
00046
00047
00048 global $wgEnablePageTranslation;
00049 if ( $wgEnablePageTranslation ) {
00050
00051 global $wgSpecialPages, $wgAvailableRights, $wgSpecialPageGroups;
00052 $wgSpecialPages['PageTranslation'] = 'SpecialPageTranslation';
00053 $wgSpecialPageGroups['PageTranslation'] = 'pagetools';
00054 $wgSpecialPages['PageTranslationDeletePage'] = 'SpecialPageTranslationDeletePage';
00055 $wgSpecialPageGroups['PageTranslationDeletePage'] = 'pagetools';
00056 $wgAvailableRights[] = 'pagetranslation';
00057
00058 global $wgLogActionsHandlers, $wgLogTypes;
00059 $wgLogTypes[] = 'pagetranslation';
00060 $wgLogActionsHandlers['pagetranslation/mark'] = 'PageTranslationLogFormatter';
00061 $wgLogActionsHandlers['pagetranslation/unmark'] = 'PageTranslationLogFormatter';
00062 $wgLogActionsHandlers['pagetranslation/moveok'] = 'PageTranslationLogFormatter';
00063 $wgLogActionsHandlers['pagetranslation/movenok'] = 'PageTranslationLogFormatter';
00064 $wgLogActionsHandlers['pagetranslation/deletelok'] = 'PageTranslationLogFormatter';
00065 $wgLogActionsHandlers['pagetranslation/deletefok'] = 'PageTranslationLogFormatter';
00066 $wgLogActionsHandlers['pagetranslation/deletelnok'] = 'PageTranslationLogFormatter';
00067 $wgLogActionsHandlers['pagetranslation/deletefnok'] = 'PageTranslationLogFormatter';
00068 $wgLogActionsHandlers['pagetranslation/encourage'] = 'PageTranslationLogFormatter';
00069 $wgLogActionsHandlers['pagetranslation/discourage'] = 'PageTranslationLogFormatter';
00070 $wgLogActionsHandlers['pagetranslation/prioritylanguages'] =
00071 'PageTranslationLogFormatter';
00072 $wgLogActionsHandlers['pagetranslation/associate'] = 'PageTranslationLogFormatter';
00073 $wgLogActionsHandlers['pagetranslation/dissociate'] = 'PageTranslationLogFormatter';
00074
00075 global $wgJobClasses;
00076 $wgJobClasses['TranslateRenderJob'] = 'TranslateRenderJob';
00077 $wgJobClasses['RenderJob'] = 'TranslateRenderJob';
00078 $wgJobClasses['TranslateMoveJob'] = 'TranslateMoveJob';
00079 $wgJobClasses['MoveJob'] = 'TranslateMoveJob';
00080 $wgJobClasses['TranslateDeleteJob'] = 'TranslateDeleteJob';
00081 $wgJobClasses['DeleteJob'] = 'TranslateDeleteJob';
00082
00083
00084 global $wgPageTranslationNamespace;
00085 global $wgNamespacesWithSubpages, $wgNamespaceProtection;
00086 global $wgTranslateMessageNamespaces;
00087
00088
00089 if ( !defined( 'NS_TRANSLATIONS' ) ) {
00090 define( 'NS_TRANSLATIONS', $wgPageTranslationNamespace );
00091 define( 'NS_TRANSLATIONS_TALK', $wgPageTranslationNamespace + 1 );
00092 }
00093
00094 $wgNamespacesWithSubpages[NS_TRANSLATIONS] = true;
00095 $wgNamespacesWithSubpages[NS_TRANSLATIONS_TALK] = true;
00096
00097
00098 $wgNamespaceProtection[NS_TRANSLATIONS] = array( 'translate' );
00099 $wgTranslateMessageNamespaces[] = NS_TRANSLATIONS;
00100
00102
00104 $wgHooks['OutputPageBeforeHTML'][] = 'PageTranslationHooks::injectCss';
00105
00106 if ( !defined( 'MW_SUPPORTS_CONTENTHANDLER' ) ) {
00107
00108 $wgHooks['ArticleSaveComplete'][] = 'PageTranslationHooks::onSectionSave';
00109 $wgHooks['ArticleSave'][] = 'PageTranslationHooks::tpSyntaxCheck';
00110 $wgHooks['EditFilterMerged'][] = 'PageTranslationHooks::tpSyntaxCheckForEditPage';
00111 $wgHooks['ArticleSaveComplete'][] = 'PageTranslationHooks::addTranstag';
00112 $wgHooks['RevisionInsertComplete'][] =
00113 'PageTranslationHooks::updateTranstagOnNullRevisions';
00114 } else {
00115
00116 $wgHooks['PageContentSaveComplete'][] = 'PageTranslationHooks::onSectionSave';
00117
00118
00119 $wgHooks['PageContentSave'][] = 'PageTranslationHooks::tpSyntaxCheck';
00120 $wgHooks['EditFilterMergedContent'][] =
00121 'PageTranslationHooks::tpSyntaxCheckForEditContent';
00122
00123
00124 $wgHooks['PageContentSaveComplete'][] = 'PageTranslationHooks::addTranstag';
00125 $wgHooks['RevisionInsertComplete'][] =
00126 'PageTranslationHooks::updateTranstagOnNullRevisions';
00127 }
00128
00129
00130 $wgHooks['ParserFirstCallInit'][] = 'TranslateHooks::setupParserHooks';
00131
00132
00133 $wgHooks['ParserBeforeStrip'][] = 'PageTranslationHooks::renderTagPage';
00134
00135
00136 $wgHooks['PageContentLanguage'][] = 'PageTranslationHooks::onPageContentLanguage';
00137
00138
00139 $wgHooks['getUserPermissionsErrorsExpensive'][] =
00140 'PageTranslationHooks::preventUnknownTranslations';
00141
00142 $wgHooks['getUserPermissionsErrorsExpensive'][] =
00143 'PageTranslationHooks::preventRestrictedTranslations';
00144
00145 $wgHooks['getUserPermissionsErrorsExpensive'][] =
00146 'PageTranslationHooks::preventDirectEditing';
00147
00148
00149 $wgHooks['ArticleViewHeader'][] = 'PageTranslationHooks::translatablePageHeader';
00150
00151
00152 $wgHooks['SpecialPage_initList'][] = 'PageTranslationHooks::replaceMovePage';
00153
00154 $wgHooks['getUserPermissionsErrorsExpensive'][] =
00155 'PageTranslationHooks::lockedPagesCheck';
00156
00157 $wgHooks['ArticleConfirmDelete'][] = 'PageTranslationHooks::disableDelete';
00158
00159
00160 $wgHooks['SkinSubPageSubtitle'][] = 'PageTranslationHooks::replaceSubtitle';
00161
00162
00163 $wgHooks['SpecialTranslate::executeTask'][] = 'PageTranslationHooks::sourceExport';
00164
00165
00166 $wgHooks['SkinTemplateNavigation'][] = 'PageTranslationHooks::translateTab';
00167 }
00168 }
00169
00178 public static function setupParserHooks( $parser ) {
00179
00180 $parser->setHook( 'languages', array( 'PageTranslationHooks', 'languages' ) );
00181
00182 return true;
00183 }
00184
00190 public static function setupUnitTests( array &$files ) {
00191 $dir = __DIR__ . '/tests/phpunit';
00192 $directoryIterator = new RecursiveDirectoryIterator( $dir );
00193 $fileIterator = new RecursiveIteratorIterator( $directoryIterator );
00194
00196 foreach ( $fileIterator as $fileInfo ) {
00197 if ( substr( $fileInfo->getFilename(), -8 ) === 'Test.php' ) {
00198 $files[] = $fileInfo->getPathname();
00199 }
00200 }
00201
00202 return true;
00203 }
00204
00210 public static function schemaUpdates( DatabaseUpdater $updater ) {
00211 $dir = __DIR__ . '/sql';
00212
00213 $updater->addExtensionUpdate( array(
00214 'addTable',
00215 'translate_sections',
00216 "$dir/translate_sections.sql",
00217 true
00218 ) );
00219 $updater->addExtensionUpdate( array(
00220 'addField',
00221 'translate_sections',
00222 'trs_order',
00223 "$dir/translate_sections-trs_order.patch.sql",
00224 true
00225 ) );
00226 $updater->addExtensionUpdate( array(
00227 'addTable',
00228 'revtag', "$dir/revtag.sql",
00229 true
00230 ) );
00231 $updater->addExtensionUpdate( array(
00232 'addTable',
00233 'translate_groupstats',
00234 "$dir/translate_groupstats.sql",
00235 true
00236 ) );
00237 $updater->addExtensionUpdate( array(
00238 'addIndex',
00239 'translate_sections',
00240 'trs_page_order',
00241 "$dir/translate_sections-indexchange.sql",
00242 true
00243 ) );
00244 $updater->addExtensionUpdate( array(
00245 'dropIndex',
00246 'translate_sections',
00247 'trs_page',
00248 "$dir/translate_sections-indexchange2.sql",
00249 true
00250 ) );
00251 $updater->addExtensionUpdate( array(
00252 'addTable',
00253 'translate_reviews',
00254 "$dir/translate_reviews.sql",
00255 true
00256 ) );
00257 $updater->addExtensionUpdate( array(
00258 'addTable',
00259 'translate_groupreviews',
00260 "$dir/translate_groupreviews.sql",
00261 true
00262 ) );
00263 $updater->addExtensionUpdate( array(
00264 'addTable',
00265 'translate_tms',
00266 "$dir/translate_tm.sql",
00267 true
00268 ) );
00269 $updater->addExtensionUpdate( array(
00270 'addTable',
00271 'translate_metadata',
00272 "$dir/translate_metadata.sql",
00273 true
00274 ) );
00275 $updater->addExtensionUpdate( array(
00276 'addTable', 'translate_messageindex',
00277 "$dir/translate_messageindex.sql",
00278 true
00279 ) );
00280 $updater->addExtensionUpdate( array(
00281 'addIndex',
00282 'translate_groupstats',
00283 'tgs_lang',
00284 "$dir/translate_groupstats-indexchange.sql",
00285 true
00286 ) );
00287 $updater->addExtensionUpdate( array(
00288 'addField', 'translate_groupstats',
00289 'tgs_proofread',
00290 "$dir/translate_groupstats-proofread.sql",
00291 true
00292 ) );
00293
00294 $updater->addExtensionUpdate( array(
00295 'addTable',
00296 'translate_stash',
00297 "$dir/translate_stash.sql",
00298 true
00299 ) );
00300
00301 return true;
00302 }
00303
00307 public static function parserTestTables( array &$tables ) {
00308 $tables[] = 'revtag';
00309 $tables[] = 'translate_groupstats';
00310 $tables[] = 'translate_messageindex';
00311 $tables[] = 'translate_stash';
00312
00313 return true;
00314 }
00315
00323 public static function onPageContentLanguage( Title $title, &$pageLang ) {
00324 $handle = new MessageHandle( $title );
00325 if ( $handle->isMessageNamespace() ) {
00326 $pageLang = $handle->getEffectiveLanguageCode();
00327 }
00328
00329 return true;
00330 }
00331
00336 public static function translateMessageDocumentationLanguage( &$names, $code ) {
00337 global $wgTranslateDocumentationLanguageCode;
00338 if ( $wgTranslateDocumentationLanguageCode ) {
00339
00340 if ( $wgTranslateDocumentationLanguageCode === $code ) {
00341 $code = 'en';
00342 }
00343
00344 $names[$wgTranslateDocumentationLanguageCode] =
00345 wfMessage( 'translate-documentation-language' )->inLanguage( $code )->plain();
00346 }
00347
00348 return true;
00349 }
00350
00354 public static function searchProfile( array &$profiles ) {
00355 global $wgTranslateMessageNamespaces;
00356 $insert = array();
00357 $insert['translation'] = array(
00358 'message' => 'translate-searchprofile',
00359 'tooltip' => 'translate-searchprofile-tooltip',
00360 'namespaces' => $wgTranslateMessageNamespaces,
00361 );
00362
00363 $profiles = wfArrayInsertAfter( $profiles, $insert, 'help' );
00364
00365 return true;
00366 }
00367
00371 public static function searchProfileForm( SpecialSearch $search, &$form,
00372 $profile, $term, array $opts
00373 ) {
00374 if ( $profile !== 'translation' ) {
00375 return true;
00376 }
00377
00378 if ( !$search->getSearchEngine()->supports( 'title-suffix-filter' ) ) {
00379 return false;
00380 }
00381
00382 $hidden = '';
00383 foreach ( $opts as $key => $value ) {
00384 $hidden .= Html::hidden( $key, $value );
00385 }
00386
00387 $context = $search->getContext();
00388 $code = $context->getLanguage()->getCode();
00389 $selected = $context->getRequest()->getVal( 'languagefilter' );
00390
00391 if ( is_callable( array( 'LanguageNames', 'getNames' ) ) ) {
00392 $languages = LanguageNames::getNames( $code,
00393 LanguageNames::FALLBACK_NORMAL,
00394 LanguageNames::LIST_MW
00395 );
00396 } else {
00397 $languages = Language::getLanguageNames( false );
00398 }
00399
00400 ksort( $languages );
00401
00402 $selector = new XmlSelect( 'languagefilter', 'languagefilter' );
00403 $selector->setDefault( $selected );
00404 $selector->addOption( wfMessage( 'translate-search-nofilter' )->text(), '-' );
00405 foreach ( $languages as $code => $name ) {
00406 $selector->addOption( "$code - $name", $code );
00407 }
00408
00409 $selector = $selector->getHTML();
00410
00411 $label = Xml::label(
00412 wfMessage( 'translate-search-languagefilter' )->text(),
00413 'languagefilter'
00414 ) . ' ';
00415 $params = array( 'id' => 'mw-searchoptions' );
00416
00417 $form = Xml::fieldset( false, false, $params ) .
00418 $hidden . $label . $selector .
00419 Html::closeElement( 'fieldset' );
00420
00421 return false;
00422 }
00423
00425 public static function searchProfileSetupEngine( SpecialSearch $search,
00426 $profile, SearchEngine $engine
00427 ) {
00428 if ( $profile !== 'translation' ) {
00429 return true;
00430 }
00431
00432 $context = $search->getContext();
00433 $selected = $context->getRequest()->getVal( 'languagefilter' );
00434 if ( $selected !== '-' && $selected ) {
00435 $engine->setFeatureData( 'title-suffix-filter', "/$selected" );
00436 $search->setExtraParam( 'languagefilter', $selected );
00437 }
00438
00439 return true;
00440 }
00441
00443 public static function hideDiscouragedFromStats( $id, $code ) {
00444
00445 return MessageGroups::getPriority( $id ) !== 'discouraged';
00446 }
00447
00449 public static function hideRestrictedFromStats( $id, $code ) {
00450 $filterLangs = TranslateMetadata::get( $id, 'prioritylangs' );
00451 if ( strlen( $filterLangs ) === 0 ) {
00452
00453 return true;
00454 }
00455
00456 $filter = array_flip( explode( ',', $filterLangs ) );
00457
00458
00459 return isset( $filter[$code] );
00460 }
00461
00463 public static function preventCategorization( LinksUpdate $updater ) {
00464 $handle = new MessageHandle( $updater->getTitle() );
00465 if ( $handle->isMessageNamespace() && !$handle->isDoc() ) {
00466 $updater->mCategories = array();
00467 }
00468
00469 return true;
00470 }
00471
00478 public static function addConfig( &$vars, OutputPage $out ) {
00479 $request = $out->getRequest();
00480 $title = $out->getTitle();
00481 list( $alias, ) = SpecialPageFactory::resolveAlias( $title->getText() );
00482
00483 if ( SpecialTranslate::isBeta( $request )
00484 && $title->isSpecialPage()
00485 && ( $alias === 'Translate'
00486 || $alias === 'TranslationStash'
00487 || $alias === 'SearchTranslations' )
00488 ) {
00489 global $wgTranslateDocumentationLanguageCode, $wgTranslatePermissionUrl;
00490 $vars['TranslateRight'] = $out->getUser()->isAllowed( 'translate' );
00491 $vars['TranslateMessageReviewRight'] =
00492 $out->getUser()->isAllowed( 'translate-messagereview' );
00493 $vars['wgTranslateDocumentationLanguageCode'] = $wgTranslateDocumentationLanguageCode;
00494 $vars['wgTranslatePermissionUrl'] = $wgTranslatePermissionUrl;
00495 }
00496
00497 return true;
00498 }
00499 }