00001 <?php
00018 class SpecialTranslate extends SpecialPage {
00022 protected $task = null;
00023
00027 protected $group = null;
00028
00029 protected $defaults = null;
00030 protected $nondefaults = array();
00031 protected $options = null;
00032
00033 function __construct() {
00034 parent::__construct( 'Translate' );
00035 }
00036
00040 public function execute( $parameters ) {
00041 global $wgTranslateBlacklist, $wgContLang;
00042
00043 $out = $this->getOutput();
00044 $out->addModules( 'ext.translate.special.translate' );
00045
00046 $this->setHeaders();
00047
00048 $request = $this->getRequest();
00049
00050 if ( $parameters === 'editpage' ) {
00051 $editpage = TranslationEditPage::newFromRequest( $request );
00052
00053 if ( $editpage ) {
00054 $editpage->execute();
00055
00056 return;
00057 }
00058 }
00059
00060 $this->setup( $parameters );
00061 $isBeta = self::isBeta( $request );
00062
00063 if ( $this->options['group'] === '' || ( $isBeta && !$this->group ) ) {
00064 $this->groupInformation();
00065
00066 return;
00067 }
00068
00069 $errors = $this->getFormErrors();
00070
00071 if ( $isBeta && $this->options['taction'] !== 'export' ) {
00072 $out->addHTML( Html::openElement( 'div', array(
00073 'class' => 'grid ext-translate-container',
00074 ) ) );
00075
00076 $out->addHTML( $this->tuxSettingsForm( $errors ) );
00077 $out->addHTML( $this->messageSelector() );
00078 } else {
00079 TranslateUtils::addSpecialHelpLink( $out, 'Help:Extension:Translate/Translation_example' );
00080
00081 $out->addHTML( $this->settingsForm( $errors ) );
00082 }
00083
00084 if ( count( $errors ) ) {
00085 return;
00086 } else {
00087 $checks = array(
00088 $this->options['group'],
00089 strtok( $this->options['group'], '-' ),
00090 '*'
00091 );
00092
00093 foreach ( $checks as $check ) {
00094 if ( isset( $wgTranslateBlacklist[$check][$this->options['language']] ) ) {
00095 $reason = $wgTranslateBlacklist[$check][$this->options['language']];
00096 $out->addWikiMsg( 'translate-page-disabled', $reason );
00097
00098 return;
00099 }
00100 }
00101 }
00102
00103 $params = array( $this->getContext(), $this->task, $this->group, $this->options );
00104 if ( !wfRunHooks( 'SpecialTranslate::executeTask', $params ) ) {
00105 return;
00106 }
00107
00108
00109 if ( !$this->task ) {
00110 return;
00111 }
00112
00113 $this->task->init( $this->group, $this->options, $this->nondefaults, $this->getContext() );
00114 $output = $this->task->execute();
00115
00116 if ( $this->task->plainOutput() ) {
00117 $out->disable();
00118 header( 'Content-type: text/plain; charset=UTF-8' );
00119 echo $output;
00120 } else {
00121 $description = $this->getGroupDescription( $this->group );
00122
00123 $taskid = $this->options['task'];
00124 if ( in_array( $taskid, array( 'untranslated', 'reviewall' ), true ) ) {
00125 $hasOptional = count( $this->group->getTags( 'optional' ) );
00126 if ( $hasOptional ) {
00127 $linktext = $this->msg( 'translate-page-description-hasoptional-open' )->escaped();
00128 $params = array( 'task' => 'optional' ) + $this->nondefaults;
00129 $link = Linker::link( $this->getTitle(), $linktext, array(), $params );
00130 $note = $this->msg( 'translate-page-description-hasoptional' )
00131 ->rawParams( $link )->parseAsBlock();
00132
00133 if ( $description ) {
00134 $description .= '<br />' . $note;
00135 } else {
00136 $description = $note;
00137 }
00138 }
00139 }
00140
00141 $status = $this->getWorkflowStatus();
00142 if ( $status !== false ) {
00143 $description = $status . $description;
00144 }
00145
00146 $groupId = $this->group->getId();
00147
00148 $priorityLangs = TranslateMetadata::get( $groupId, 'prioritylangs' );
00149 $priorityLangs = array_flip( array_filter( explode( ',', $priorityLangs ) ) );
00150 $priorityLangsCount = count( $priorityLangs );
00151 if ( $priorityLangsCount && !isset( $priorityLangs[$this->options['language']] ) ) {
00152 $priorityForce = TranslateMetadata::get( $groupId, 'priorityforce' );
00153 if ( $priorityForce === 'on' ) {
00154
00155 $priorityMessageClass = 'errorbox';
00156 $priorityMessageKey = 'tpt-discouraged-language-force';
00157 } else {
00158 $priorityMessageClass = 'warningbox';
00159 $priorityMessageKey = 'tpt-discouraged-language';
00160 }
00161
00162 $priorityLanguageNames = array();
00163 $languageNames = TranslateUtils::getLanguageNames( $this->getLanguage()->getCode() );
00164 foreach ( array_keys( $priorityLangs ) as $langCode ) {
00165 $priorityLanguageNames[] = $languageNames[$langCode];
00166 }
00167
00168 $priorityReason = TranslateMetadata::get( $groupId, 'priorityreason' );
00169 if ( $priorityReason !== '' ) {
00170 $priorityReason = "\n\n" . $this->msg(
00171 'tpt-discouraged-language-reason',
00172 Xml::element( 'span',
00173
00174 array(
00175 'lang' => $wgContLang->getCode(),
00176 'dir' => $wgContLang->getDir(),
00177 ),
00178 $priorityReason
00179 )
00180 )->parse();
00181 }
00182
00183 $description .= Html::RawElement( 'div',
00184 array( 'class' => $priorityMessageClass ),
00185 $this->msg(
00186 $priorityMessageKey,
00187 '',
00188 $languageNames[$this->options['language']],
00189 $this->getLanguage()->listToText( $priorityLanguageNames )
00190 )->parseAsBlock() . $priorityReason
00191 );
00192 }
00193
00194 if ( $description ) {
00195 $description = Xml::fieldset(
00196 $this->msg( 'translate-page-description-legend' )->text(),
00197 $description,
00198 array( 'class' => 'mw-sp-translate-description' )
00199 );
00200 }
00201
00202 if ( $isBeta ) {
00203 $out->addHTML( $output );
00204 } else {
00205 $out->addHTML( $description . $output );
00206 }
00207
00208 ApiTranslateUser::trackGroup( $this->group, $this->getUser() );
00209 }
00210
00211 if ( $isBeta ) {
00212 $out->addHTML( Html::closeElement( 'div' ) );
00213 }
00214 }
00215
00219 protected function getFormErrors() {
00220 $errors = array();
00221
00222 $codes = TranslateUtils::getLanguageNames( 'en' );
00223 if ( !$this->options['language'] || !isset( $codes[$this->options['language']] ) ) {
00224 $errors['language'] = $this->msg( 'translate-page-no-such-language' )->text();
00225 $this->options['language'] = $this->defaults['language'];
00226 }
00227
00228 if ( !$this->group instanceof MessageGroup ) {
00229 $errors['group'] = $this->msg( 'translate-page-no-such-group' )->text();
00230 $this->options['group'] = $this->defaults['group'];
00231 } else {
00232 $languages = $this->group->getTranslatableLanguages();
00233
00234 if ( $languages !== null && !isset( $languages[$this->options['language']] ) ) {
00235 $errors['language'] = $this->msg( 'translate-language-disabled' )->text();
00236 }
00237 }
00238
00239 return $errors;
00240 }
00241
00242 protected function setup( $parameters ) {
00243 $request = $this->getRequest();
00244 $isBeta = self::isBeta( $request );
00245
00246 $defaults = array(
00247 'taction' => 'translate',
00248 'task' => $isBeta ? 'custom' : 'untranslated',
00249 'language' => $this->getLanguage()->getCode(),
00250 'group' => $isBeta ? '!additions' : '',
00251 'offset' => '',
00252 'limit' => $isBeta ? 0 : 100,
00253 'optional' => '0',
00254 );
00255
00256
00257 $nondefaults = array();
00258
00259 $parameters = array_map( 'trim', explode( ';', $parameters ) );
00260 $pars = array();
00261
00262 foreach ( $parameters as $_ ) {
00263 if ( $_ === '' ) {
00264 continue;
00265 }
00266
00267 if ( strpos( $_, '=' ) !== false ) {
00268 list( $key, $value ) = array_map( 'trim', explode( '=', $_, 2 ) );
00269 } else {
00270 $key = 'group';
00271 $value = $_;
00272 }
00273
00274 $pars[$key] = $value;
00275 }
00276
00277 foreach ( $defaults as $v => $t ) {
00278 if ( is_bool( $t ) ) {
00279 $r = isset( $pars[$v] ) ? (bool)$pars[$v] : $defaults[$v];
00280 $r = $request->getBool( $v, $r );
00281 } elseif ( is_int( $t ) ) {
00282 $r = isset( $pars[$v] ) ? (int)$pars[$v] : $defaults[$v];
00283 $r = $request->getInt( $v, $r );
00284 } elseif ( is_string( $t ) ) {
00285 $r = isset( $pars[$v] ) ? (string)$pars[$v] : $defaults[$v];
00286 $r = $request->getText( $v, $r );
00287 }
00288
00289 if ( !isset( $r ) ) {
00290 throw new MWException( '$r was not set' );
00291 }
00292
00293 wfAppendToArrayIfNotDefault( $v, $r, $defaults, $nondefaults );
00294 }
00295
00296
00297 if ( isset( $nondefaults['taction'] ) ) {
00298 if ( $nondefaults['taction'] === 'proofread' ) {
00299 if ( $this->getUser()->isAllowed( 'translate-messagereview' ) ) {
00300 $defaults['task'] = 'acceptqueue';
00301 } else {
00302 $defaults['task'] = 'reviewall';
00303 }
00304 } elseif ( $nondefaults['taction'] === 'export' ) {
00305 $defaults['task'] = '';
00306 }
00307 }
00308
00309 if ( $isBeta ) {
00310
00311
00312
00313
00314
00315
00316 $this->rewriteLegacyUrls( $nondefaults );
00317 }
00318
00319 $this->defaults = $defaults;
00320 $this->nondefaults = $nondefaults;
00321 wfRunHooks( 'TranslateGetSpecialTranslateOptions', array( &$defaults, &$nondefaults ) );
00322
00323 $this->options = $nondefaults + $defaults;
00324 $this->group = MessageGroups::getGroup( $this->options['group'] );
00325 $this->task = TranslateTasks::getTask( $this->options['task'] );
00326
00327 if ( $this->group && MessageGroups::isDynamic( $this->group ) ) {
00328 $this->group->setLanguage( $this->options['language'] );
00329 }
00330 }
00331
00332 protected function rewriteLegacyUrls( $params ) {
00333 if (
00334 !isset( $params['task'] ) &&
00335 isset( $params['taction'] ) && $params['taction'] === 'proofread'
00336 ) {
00337 $params['task'] = 'acceptqueue';
00338 }
00339
00340 if ( !isset( $params['task'] ) || $params['task'] === 'custom' ) {
00341 return;
00342 }
00343
00344
00345 unset( $params['taction'], $params['limit'], $params['offset'] );
00346
00347 $out = $this->getOutput();
00348
00349 switch ( $params['task'] ) {
00350 case 'reviewall':
00351 case 'acceptqueue':
00352
00353 unset( $params['task'] );
00354 $params['action'] = 'proofread';
00355 $out->redirect( $this->getTitle()->getLocalUrl( $params ) );
00356 break;
00357
00358 case 'view':
00359 unset( $params['task'] );
00360 $params['filter'] = '';
00361 $out->redirect( $this->getTitle()->getLocalUrl( $params ) );
00362 break;
00363
00364
00365
00366 case 'optional':
00367 $params['optional'] = 1;
00368 case 'untranslated':
00369 unset( $params['task'] );
00370 $params['filter'] = '!translated';
00371 $out->redirect( $this->getTitle()->getLocalUrl( $params ) );
00372 break;
00373 }
00374 }
00375
00376 protected function settingsForm( $errors ) {
00377 global $wgScript;
00378
00379 $taction = $this->options['taction'];
00380
00381 $selectors = array(
00382 'group' => $this->groupSelector(),
00383 'language' => $this->languageSelector(),
00384 'limit' => $this->limitSelector(),
00385 );
00386
00387 if ( $taction === 'export' ) {
00388 unset( $selectors['limit'] );
00389 }
00390
00391 $options = array();
00392 foreach ( $selectors as $g => $selector ) {
00393
00394
00395 $options[] = self::optionRow(
00396 $this->msg( 'translate-page-' . $g )->escaped(),
00397 $selector,
00398 array_key_exists( $g, $errors ) ? $errors[$g] : null
00399 );
00400 }
00401
00402 if ( $taction === 'proofread' ) {
00403 $extra = $this->taskLinks( array( 'acceptqueue', 'reviewall' ) );
00404 } elseif ( $taction === 'translate' ) {
00405 $extra = $this->taskLinks( array( 'view', 'untranslated', 'optional' ) );
00406 } elseif ( $taction === 'export' ) {
00407 $extra = $this->taskLinks( array( 'export-as-po', 'export-to-file' ) );
00408 } else {
00409 $extra = '';
00410 }
00411
00412 $nonEssential = Html::rawElement(
00413 'span',
00414 array( 'class' => 'mw-sp-translate-nonessential' ),
00415 implode( "", $options )
00416 );
00417
00418 $button = Xml::submitButton( $this->msg( 'translate-submit' )->text() );
00419
00420 $formAttributes = array( 'class' => 'mw-sp-translate-settings' );
00421 if ( $this->group ) {
00422 $formAttributes['data-grouptype'] = get_class( $this->group );
00423 }
00424 $form =
00425 Html::openElement( 'fieldset', $formAttributes ) .
00426 Html::element( 'legend', array(), $this->msg( 'translate-page-settings-legend' )->text() ) .
00427 Html::openElement( 'form', array( 'action' => $wgScript, 'method' => 'get' ) ) .
00428 Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
00429 Html::hidden( 'taction', $this->options['taction'] ) .
00430 "$nonEssential\n$extra\n$button\n" .
00431 Html::closeElement( 'form' ) .
00432 Html::closeElement( 'fieldset' );
00433
00434 return $form;
00435 }
00436
00437 protected function tuxSettingsForm() {
00438 $attrs = array( 'class' => 'row tux-editor-header' );
00439 $selectors = $this->tuxGroupSelector() .
00440 $this->tuxLanguageSelector() .
00441 $this->tuxGroupDescription() .
00442 $this->tuxWorkflowSelector() .
00443 $this->tuxGroupWarning();
00444
00445 return Html::rawElement( 'div', $attrs, $selectors );
00446 }
00447
00448 protected function messageSelector() {
00449 $output = Html::openElement( 'div', array( 'class' => 'row tux-messagetable-header' ) );
00450 $output .= Html::openElement( 'div', array( 'class' => 'nine columns' ) );
00451 $output .= Html::openElement( 'ul', array( 'class' => 'row tux-message-selector' ) );
00452 $userId = $this->getUser()->getId();
00453 $tabs = array(
00454 'all' => '',
00455 'untranslated' => '!translated',
00456
00457 'outdated' => 'fuzzy',
00458 'translated' => 'translated',
00459 'unproofread' => "translated|!reviewer:$userId|!last-translator:$userId",
00460 );
00461
00462 $params = $this->nondefaults;
00463 $params['task'] = 'custom';
00464
00465 foreach ( $tabs as $tab => $filter ) {
00466
00467
00468
00469
00470
00471
00472 $tabClass = "tux-tab-$tab";
00473 $taskParams = array( 'filter' => $filter ) + $params;
00474 ksort( $taskParams );
00475 $href = $this->getTitle()->getLocalUrl( $taskParams );
00476 $link = Html::element( 'a', array( 'href' => $href ), $this->msg( $tabClass ) );
00477 $output .= Html::rawElement( 'li', array(
00478 'class' => 'column ' . $tabClass,
00479 'data-filter' => $filter,
00480 'data-title' => $tab,
00481 ), $link );
00482 }
00483
00484
00485
00486
00487
00488
00489 $options = array(
00490 'optional' => $this->msg( 'tux-message-filter-optional-messages-label' )->escaped(),
00491 );
00492
00493 $container = Html::openElement( 'ul', array( 'class' => 'column tux-message-selector' ) );
00494 foreach ( $options as $optFilter => $optLabel ) {
00495 $container .= Html::rawElement( 'li',
00496 array( 'class' => 'column' ),
00497 Xml::checkLabel(
00498 $optLabel,
00499 $optFilter,
00500 "tux-option-$optFilter",
00501 isset( $this->nondefaults[$optFilter] ),
00502 array( 'data-filter' => $optFilter )
00503 )
00504 );
00505 }
00506
00507 $container .= Html::closeElement( 'ul' );
00508
00509
00510 $output .= Html::openElement( 'li', array( 'class' => 'column more' ) ) .
00511 '...' .
00512 $container .
00513 Html::closeElement( 'li' );
00514
00515 $output .= Html::closeElement( 'ul' );
00516 $output .= Html::closeElement( 'div' );
00517 $output .= Html::openElement( 'div', array( 'class' => 'three columns' ) );
00518 $output .= Html::element( 'span', array( 'class' => 'two columns tux-message-filter-box-icon' ) );
00519 $output .= Html::element( 'input', array(
00520 'class' => 'ten columns tux-message-filter-box',
00521 'type' => 'search',
00522 ) );
00523
00524 $output .= Html::closeElement( 'div' );
00525
00526 $output .= Html::closeElement( 'div' );
00527
00528 return $output;
00529 }
00530
00531 protected function tuxGroupSelector() {
00532 $group = MessageGroups::getGroup( $this->options['group'] );
00533
00534
00535 $output = Html::openElement( 'div', array(
00536 'class' => 'eight columns ext-translate-msggroup-selector',
00537 'data-language' => $this->options['language'],
00538 ) ) .
00539 Html::element( 'span',
00540 array( 'class' => 'grouptitle' ),
00541 $this->msg( 'translate-msggroupselector-projects' )->escaped()
00542 ) .
00543 Html::element( 'span',
00544 array( 'class' => 'grouptitle grouplink expanded' ),
00545 $this->msg( 'translate-msggroupselector-search-all' )->escaped()
00546 ) .
00547 Html::element( 'span',
00548 array(
00549 'class' => 'grouptitle grouplink tail',
00550 'data-msggroupid' => $this->options['group'],
00551 ),
00552 $group->getLabel()
00553 ) .
00554 Html::closeElement( 'div' );
00555
00556 return $output;
00557 }
00558
00559 protected function tuxLanguageSelector() {
00560
00561
00562 global $wgTranslateDocumentationLanguageCode;
00563
00564 if ( $this->options['language'] === $wgTranslateDocumentationLanguageCode ) {
00565
00566
00567 $targetLangCode = $this->getLanguage()->getCode();
00568 $targetLangDir = $this->getLanguage()->getDir();
00569 $targetLangName = $this->msg( 'translate-documentation-language' )->text();
00570 } else {
00571 $targetLangCode = $this->options['language'];
00572 $targetLangDir = Language::factory( $this->options['language'] )->getDir();
00573 $targetLangName = Language::fetchLanguageName( $this->options['language'] );
00574 }
00575
00576
00577
00578 return Html::rawElement( 'div',
00579 array( 'class' => 'four columns ext-translate-language-selector' ),
00580 Html::element( 'span',
00581 array( 'class' => 'ext-translate-language-selector-label' ),
00582 $this->msg( 'tux-languageselector' )->text()
00583 ) .
00584 ' ' .
00585 Html::element( 'span',
00586 array(
00587 'class' => 'uls',
00588 'lang' => $targetLangCode,
00589 'dir' => $targetLangDir,
00590 ),
00591 $targetLangName
00592 )
00593 );
00594 }
00595
00596 protected function tuxGroupDescription() {
00597 return Html::rawElement(
00598 'div',
00599 array( 'class' => 'twelve columns description' ),
00600 $this->getGroupDescription( $this->group )
00601 );
00602 }
00603
00604 protected function tuxGroupWarning() {
00605
00606 return Html::element(
00607 'div',
00608 array( 'class' => 'twelve columns group-warning' ),
00609 ''
00610 );
00611 }
00612
00619 private static function optionRow( $label, $option, $error = null ) {
00620 return "<label>$label $option</label>" .
00621 ( $error ?
00622 Html::rawElement( 'span', array( 'class' => 'mw-sp-translate-error' ), $error ) :
00623 ''
00624 ) . ' ';
00625 }
00626
00627 protected function taskLinks( $tasks ) {
00628 $user = $this->getUser();
00629
00630 foreach ( $tasks as $index => $id ) {
00631 $task = TranslateTasks::getTask( $id );
00632
00633 if ( !$task ) {
00634 unset( $tasks[$index] );
00635 continue;
00636 }
00637
00638 if ( !$task->isAllowedFor( $user ) ) {
00639 unset( $tasks[$index] );
00640 continue;
00641 }
00642 }
00643
00644 $sep = Html::element( 'br' );
00645 $count = count( $tasks );
00646 if ( $count === 0 ) {
00647 return $sep . $this->msg( 'translate-taction-disabled' )->escaped();
00648 } elseif ( $count === 1 ) {
00649 $id = array_pop( $tasks );
00650
00651
00652
00653
00654
00655 if ( $this->defaults['task'] === $id ) {
00656 return '';
00657 }
00658
00659
00660
00661
00662
00663 return $sep . Html::rawElement( 'label', array(),
00664 Xml::radio( 'task', $id, true ) . ' ' .
00665 $this->msg( "translate-taskui-$id" )->escaped()
00666 );
00667 } else {
00668 $output = '';
00669
00670 foreach ( $tasks as $id ) {
00671
00672
00673
00674
00675 $output .= Html::rawElement( 'label', array(),
00676 Xml::radio( 'task', $id, $this->options['task'] === $id ) . ' ' .
00677 $this->msg( "translate-taskui-$id" )->escaped()
00678 ) . ' ';
00679 }
00680
00681 return $sep . $output;
00682 }
00683 }
00684
00685 protected function groupSelector() {
00686 $groups = MessageGroups::getAllGroups();
00687 uasort( $groups, array( 'MessageGroups', 'groupLabelSort' ) );
00688 $dynamic = MessageGroups::getDynamicGroups();
00689 $groups = array_keys( array_merge( $dynamic, $groups ) );
00690
00691 $selected = $this->options['group'];
00692
00693 $selector = new XmlSelect( 'group', 'group' );
00694 $selector->setDefault( $selected );
00695
00696 foreach ( $groups as $id ) {
00697 $group = MessageGroups::getGroup( $id );
00698 $hide = MessageGroups::getPriority( $group ) === 'discouraged';
00699
00700 if ( !$group->exists() || ( $hide && $id !== $selected ) ) {
00701 continue;
00702 }
00703
00704 $selector->addOption( $group->getLabel(), $id );
00705 }
00706
00707 return $selector->getHTML();
00708 }
00709
00710 protected function languageSelector() {
00711 return TranslateUtils::languageSelector(
00712 $this->getLanguage()->getCode(),
00713 $this->options['language']
00714 );
00715 }
00716
00717 protected function limitSelector() {
00718 $items = array( 100, 1000, 5000 );
00719 $selector = new XmlSelect( 'limit', 'limit' );
00720 $selector->setDefault( $this->options['limit'] );
00721
00722 foreach ( $items as $count ) {
00723 $selector->addOption(
00724 $this->msg( 'translate-page-limit-option' )->numParams( $count )->text(),
00725 $count
00726 );
00727 }
00728
00729 return $selector->getHTML();
00730 }
00731
00732 protected function getGroupDescription( MessageGroup $group ) {
00733 $description = $group->getDescription( $this->getContext() );
00734 if ( $description !== null ) {
00735 return $this->getOutput()->parse( $description, false );
00736 }
00737
00738 return '';
00739 }
00740
00745 public function groupInformation() {
00746 $output = $this->getOutput();
00747
00748
00749
00750 if ( self::isBeta( $this->getRequest() ) ) {
00751 $output->addHtml( Html::rawElement(
00752 'div',
00753 array( 'class' => 'twelve columns group-warning' ),
00754 $this->msg( 'tux-translate-page-no-such-group' )->parse()
00755 ) );
00756 }
00757
00758 $output->addHtml(
00759 Html::openElement( 'div', array(
00760 'class' => 'eight columns ext-translate-msggroup-selector',
00761 'data-language' => $this->options['language'],
00762 ) ) .
00763 '<span class="grouptitle">' .
00764 $this->msg( 'translate-msggroupselector-projects' )->escaped() .
00765 '</span>
00766 <span class="grouptitle grouplink tail">' .
00767 $this->msg( 'translate-msggroupselector-search-all' )->escaped() .
00768 '</span>
00769 </div>'
00770 );
00771 }
00772
00773 protected function tuxWorkflowSelector() {
00774 return Html::element( 'div', array( 'class' => 'tux-workflow twelve columns' ) );
00775 }
00776
00777 protected function getWorkflowStatus() {
00778 $stateConfig = $this->group->getMessageGroupStates()->getStates();
00779 if ( !$stateConfig ) {
00780 return false;
00781 }
00782
00783 if ( MessageGroups::isDynamic( $this->group ) ) {
00784 return false;
00785 }
00786
00787 $dbr = wfGetDB( DB_SLAVE );
00788 $current = $dbr->selectField(
00789 'translate_groupreviews',
00790 'tgr_state',
00791 array( 'tgr_group' => $this->options['group'], 'tgr_lang' => $this->options['language'] ),
00792 __METHOD__
00793 );
00794
00795 $options = array();
00796 $stateConfig = array_merge(
00797 array( '' => array( 'right' => 'impossible-right' ) ),
00798 $stateConfig
00799 );
00800
00801 $user = $this->getUser();
00802 if ( $user->isAllowed( 'translate-groupreview' ) ) {
00803
00804 foreach ( $stateConfig as $state => $config ) {
00805 $stateMessage = $this->msg( "translate-workflow-state-$state" );
00806 $stateText = $stateMessage->isBlank() ? $state : $stateMessage->text();
00807
00808 $attributes = array(
00809 'value' => $state,
00810 );
00811
00812 if ( $state === strval( $current ) ) {
00813 $attributes['selected'] = 'selected';
00814 }
00815
00816 if ( is_array( $config ) && isset( $config['right'] )
00817 && !$user->isAllowed( $config['right'] )
00818 ) {
00819
00820 $attributes['disabled'] = 'disabled';
00821 }
00822
00823 $options[] = Html::element( 'option', $attributes, $stateText );
00824 }
00825 $stateIndicator = Html::rawElement( 'select',
00826 array(
00827 'class' => 'mw-translate-workflowselector',
00828 'name' => 'workflow',
00829 ),
00830 implode( "\n", $options )
00831 );
00832
00833 $setButtonAttributes = array(
00834 'type' => 'button',
00835 'id' => 'mw-translate-workflowset',
00836 'data-token' => ApiGroupReview::getToken( 0, '' ),
00837 'data-group' => $this->options['group'],
00838 'data-language' => $this->options['language'],
00839 'style' => 'visibility: hidden;',
00840 'value' => 'Set',
00841 );
00842 $stateIndicator .= Html::element( 'input', $setButtonAttributes );
00843 } elseif ( strval( $current ) !== '' ) {
00844 $stateIndicator = $current;
00845 } else {
00846 $stateIndicator = $this->msg( 'translate-workflow-state-' )->escaped();
00847 }
00848
00849 $message = $this->msg( 'translate-workflowstatus' )->rawParams( $stateIndicator );
00850 $box = Html::rawElement(
00851 'div',
00852 array( 'id' => 'mw-sp-translate-workflow' ),
00853 $message->escaped()
00854 );
00855
00856 return $box;
00857 }
00858
00864 static function tabify( Skin $skin, array &$tabs ) {
00865 $title = $skin->getTitle();
00866 list( $alias, $sub ) = SpecialPageFactory::resolveAlias( $title->getText() );
00867
00868 $pagesInGroup = array( 'Translate', 'LanguageStats', 'MessageGroupStats' );
00869 if ( !in_array( $alias, $pagesInGroup, true ) ) {
00870 return true;
00871 }
00872
00873 $skin->getOutput()->addModules( 'ext.translate.tabgroup' );
00874
00875
00876 $params = array();
00877 if ( trim( $sub ) !== '' ) {
00878 if ( $alias === 'Translate' || $alias === 'MessageGroupStats' ) {
00879 $params['group'] = $sub;
00880 } elseif ( $alias === 'LanguageStats' ) {
00881
00882 $params['language'] = $sub;
00883 }
00884 }
00885
00886 $request = $skin->getRequest();
00887
00888 $params['language'] = $request->getVal( 'language' );
00889 $params['group'] = $request->getVal( 'group' );
00890
00891 $taction = $request->getVal( 'taction', 'translate' );
00892
00893 $translate = SpecialPage::getTitleFor( 'Translate' );
00894 $languagestats = SpecialPage::getTitleFor( 'LanguageStats' );
00895 $messagegroupstats = SpecialPage::getTitleFor( 'MessageGroupStats' );
00896
00897
00898 $tabs['namespaces'] = array();
00899
00900 $tabs['namespaces']['translate'] = array(
00901 'text' => wfMessage( 'translate-taction-translate' )->text(),
00902 'href' => $translate->getLocalUrl( $params ),
00903 'class' => 'tux-tab',
00904 );
00905
00906 if ( $alias === 'Translate' && $taction === 'translate' ) {
00907 $tabs['namespaces']['translate']['class'] .= ' selected';
00908 }
00909
00910 if ( !self::isBeta( $request ) ) {
00911 $tabs['namespaces']['proofread'] = array(
00912 'text' => wfMessage( 'translate-taction-proofread' )->text(),
00913 'href' => $translate->getLocalUrl( array( 'taction' => 'proofread' ) + $params ),
00914 'class' => 'tux-tab',
00915 );
00916
00917 if ( $alias === 'Translate' && $taction === 'proofread' ) {
00918 $tabs['namespaces']['proofread']['class'] .= ' selected';
00919 }
00920 }
00921
00922 $tabs['views']['lstats'] = array(
00923 'text' => wfMessage( 'translate-taction-lstats' )->text(),
00924 'href' => $languagestats->getLocalUrl( $params ),
00925 'class' => 'tux-tab',
00926 );
00927 if ( $alias === 'LanguageStats' ) {
00928 $tabs['views']['lstats']['class'] .= ' selected';
00929 }
00930
00931 $tabs['views']['mstats'] = array(
00932 'text' => wfMessage( 'translate-taction-mstats' )->text(),
00933 'href' => $messagegroupstats->getLocalUrl( $params ),
00934 'class' => 'tux-tab',
00935 );
00936
00937 if ( $alias === 'MessageGroupStats' ) {
00938 $tabs['views']['mstats']['class'] .= ' selected';
00939 }
00940
00941
00942 global $wgTranslateTasks;
00943 foreach ( array_keys( $wgTranslateTasks ) as $taskname ) {
00944 if ( !preg_match( '/^export-/', $taskname ) ) {
00945 continue;
00946 }
00947
00948 $tabs['views']['export'] = array(
00949 'text' => wfMessage( 'translate-taction-export' )->text(),
00950 'href' => $translate->getLocalUrl( array( 'taction' => 'export' ) + $params ),
00951 'class' => 'tux-tab',
00952 );
00953
00954 if ( $alias === 'Translate' && $taction === 'export' ) {
00955 $tabs['views']['export']['class'] .= ' selected';
00956 }
00957
00958
00959 break;
00960 }
00961
00962 return true;
00963 }
00964
00965 public static function isBeta( WebRequest $request ) {
00966 global $wgTranslateUseTux;
00967
00968 $tux = $request->getVal( 'tux', null );
00969
00970 if ( $tux === null ) {
00971 $tux = $request->getCookie( 'tux', null, $wgTranslateUseTux );
00972 } elseif ( $tux ) {
00973 $request->response()->setCookie( 'tux', 1 );
00974 } else {
00975 $request->response()->setCookie( 'tux', 0 );
00976 }
00977
00978 return $tux;
00979 }
00980 }