SpecialPageTranslation.php

Go to the documentation of this file.
00001 <?php
00021 class SpecialPageTranslation extends SpecialPage {
00022     function __construct() {
00023         parent::__construct( 'PageTranslation' );
00024     }
00025 
00026     public function execute( $parameters ) {
00027         $this->setHeaders();
00028 
00029         $user = $this->getUser();
00030         $request = $this->getRequest();
00031 
00032         $target = $request->getText( 'target', $parameters );
00033         $revision = $request->getInt( 'revision', 0 );
00034         $action = $request->getVal( 'do' );
00035         $out = $this->getOutput();
00036 
00037         TranslateUtils::addSpecialHelpLink(
00038             $out,
00039             'Help:Extension:Translate/Page_translation_example'
00040         );
00041 
00042         // No specific page or invalid input
00043         $title = Title::newFromText( $target );
00044         if ( !$title ) {
00045             if ( $target !== '' ) {
00046                 $out->addWikiMsg( 'tpt-badtitle' );
00047             } else {
00048                 $this->listPages();
00049             }
00050 
00051             return;
00052         }
00053 
00054         // Check permissions
00055         if ( !$user->isAllowed( 'pagetranslation' ) ) {
00056             throw new PermissionsError( 'pagetranslation' );
00057         }
00058 
00059         // Check permissions
00060         if ( $request->wasPosted() && !$user->matchEditToken( $request->getText( 'token' ) ) ) {
00061             throw new PermissionsError( 'pagetranslation' );
00062         }
00063 
00064         // We are processing some specific page
00065         if ( !$title->exists() ) {
00066             $out->addWikiMsg( 'tpt-nosuchpage', $title->getPrefixedText() );
00067 
00068             return;
00069         }
00070 
00071         if ( $action === 'discourage' || $action === 'encourage' ) {
00072             $id = TranslatablePage::getMessageGroupIdFromTitle( $title );
00073             $current = MessageGroups::getPriority( $id );
00074 
00075             if ( $action === 'encourage' ) {
00076                 $new = '';
00077             } else {
00078                 $new = 'discouraged';
00079             }
00080 
00081             if ( $new !== $current ) {
00082                 MessageGroups::setPriority( $id, $new );
00083                 $entry = new ManualLogEntry( 'pagetranslation', $action );
00084                 $entry->setPerformer( $user );
00085                 $entry->setTarget( $title );
00086                 $logid = $entry->insert();
00087                 $entry->publish( $logid );
00088             }
00089 
00090             $this->listPages();
00091 
00092             $group = MessageGroups::getGroup( $id );
00093             $parents = MessageGroups::getSharedGroups( $group );
00094             MessageGroupStats::clearGroup( $parents );
00095 
00096             return;
00097         }
00098 
00099         if ( $action === 'unmark' ) {
00100             $page = TranslatablePage::newFromTitle( $title );
00101             $page->unmarkTranslatablePage();
00102             $page->getTitle()->invalidateCache();
00103 
00104             $entry = new ManualLogEntry( 'pagetranslation', 'unmark' );
00105             $entry->setPerformer( $user );
00106             $entry->setTarget( $page->getTitle() );
00107             $logid = $entry->insert();
00108             $entry->publish( $logid );
00109 
00110             $out->addWikiMsg( 'tpt-unmarked', $title->getPrefixedText() );
00111 
00112             return;
00113         }
00114 
00115         if ( $revision === 0 ) {
00116             // Get the latest revision
00117             $revision = intval( $title->getLatestRevID() );
00118         }
00119 
00120         $page = TranslatablePage::newFromRevision( $title, $revision );
00121         if ( !$page instanceof TranslatablePage ) {
00122             $out->addWikiMsg( 'tpt-notsuitable', $title->getPrefixedText(), $revision );
00123 
00124             return;
00125         }
00126 
00127         if ( $revision !== intval( $title->getLatestRevID() ) ) {
00128             // We do want to notify the reviewer if the underlying page changes during review
00129             $target = $title->getFullUrl( array( 'oldid' => $revision ) );
00130             $link = "<span class='plainlinks'>[$target $revision]</span>";
00131             $out->addWikiMsg( 'tpt-oldrevision', $title->getPrefixedText(), $link );
00132 
00133             return;
00134         }
00135 
00136         $lastrev = $page->getMarkedTag();
00137         if ( $lastrev !== false && $lastrev === $revision ) {
00138             $out->addWikiMsg( 'tpt-already-marked' );
00139             $this->listPages();
00140 
00141             return;
00142         }
00143 
00144         // This will modify the sections to include name property
00145         $error = false;
00146         $sections = $this->checkInput( $page, $error );
00147 
00148         // Non-fatal error which prevents saving
00149         if ( $error === false && $request->wasPosted() ) {
00150             $err = $this->markForTranslation( $page, $sections );
00151 
00152             if ( $err ) {
00153                 call_user_func_array( array( $out, 'addWikiMsg' ), $err );
00154             } else {
00155                 $this->showSuccess( $page );
00156                 $this->listPages();
00157             }
00158 
00159             return;
00160         }
00161 
00162         $this->showPage( $page, $sections );
00163     }
00164 
00168     public function showSuccess( TranslatablePage $page ) {
00169         $titleText = $page->getTitle()->getPrefixedText();
00170         $num = $this->getLanguage()->formatNum( $page->getParse()->countSections() );
00171         $link = SpecialPage::getTitleFor( 'Translate' )->getFullUrl(
00172             array( 'group' => $page->getMessageGroupId() ) );
00173 
00174         $this->getOutput()->addWikiMsg( 'tpt-saveok', $titleText, $num, $link );
00175         // If TranslationNotifications is installed, and the user can notify
00176         // translators, add a convenience link.
00177         if ( method_exists( 'SpecialNotifyTranslators', 'execute' ) &&
00178             $this->getUser()->isAllowed( SpecialNotifyTranslators::$right )
00179         ) {
00180             $link = SpecialPage::getTitleFor( 'NotifyTranslators' )->getFullUrl(
00181                 array( 'tpage' => $page->getTitle()->getArticleID() ) );
00182             $this->getOutput()->addWikiMsg( 'tpt-offer-notify', $link );
00183         }
00184     }
00185 
00186     public function loadPagesFromDB() {
00187         $dbr = wfGetDB( DB_MASTER );
00188         $tables = array( 'page', 'revtag' );
00189         $vars = array(
00190             'page_id',
00191             'page_title',
00192             'page_namespace',
00193             'page_latest',
00194             'MAX(rt_revision) AS rt_revision',
00195             'rt_type'
00196         );
00197         $conds = array(
00198             'page_id=rt_page',
00199             'rt_type' => array( RevTag::getType( 'tp:mark' ), RevTag::getType( 'tp:tag' ) ),
00200         );
00201         $options = array(
00202             'ORDER BY' => 'page_namespace, page_title',
00203             'GROUP BY' => 'page_id, rt_type',
00204         );
00205         $res = $dbr->select( $tables, $vars, $conds, __METHOD__, $options );
00206 
00207         return $res;
00208     }
00209 
00210     protected function buildPageArray( /*db result*/$res ) {
00211         $pages = array();
00212         foreach ( $res as $r ) {
00213             // We have multiple rows for same page, because of different tags
00214             if ( !isset( $pages[$r->page_id] ) ) {
00215                 $pages[$r->page_id] = array();
00216                 $title = Title::newFromRow( $r );
00217                 $pages[$r->page_id]['title'] = $title;
00218                 $pages[$r->page_id]['latest'] = intval( $title->getLatestRevID() );
00219             }
00220 
00221             $tag = RevTag::typeToTag( $r->rt_type );
00222             $pages[$r->page_id][$tag] = intval( $r->rt_revision );
00223         }
00224 
00225         return $pages;
00226     }
00227 
00232     protected function classifyPages( array $in ) {
00233         $out = array(
00234             'proposed' => array(),
00235             'active' => array(),
00236             'broken' => array(),
00237             'discouraged' => array(),
00238         );
00239 
00240         foreach ( $in as $index => $page ) {
00241             if ( !isset( $page['tp:mark'] ) ) {
00242                 // Never marked, check that the latest version is ready
00243                 if ( $page['tp:tag'] === $page['latest'] ) {
00244                     $out['proposed'][$index] = $page;
00245                 } // Otherwise ignore such pages
00246             } elseif ( $page['tp:tag'] === $page['latest'] ) {
00247                 // Marked and latest version if fine
00248                 $out['active'][$index] = $page;
00249             } else {
00250                 // Marked but latest version if not fine
00251                 $out['broken'][$index] = $page;
00252             }
00253         }
00254 
00255         // broken and proposed take preference over discouraged status
00256         foreach ( $out['active'] as $index => $page ) {
00257             $id = TranslatablePage::getMessageGroupIdFromTitle( $page['title'] );
00258             $group = MessageGroups::getGroup( $id );
00259             if ( MessageGroups::getPriority( $group ) === 'discouraged' ) {
00260                 $out['discouraged'][$index] = $page;
00261                 unset( $out['active'][$index] );
00262             }
00263         }
00264 
00265         return $out;
00266     }
00267 
00268     public function listPages() {
00269         $out = $this->getOutput();
00270 
00271         $res = $this->loadPagesFromDB();
00272         $allpages = $this->buildPageArray( $res );
00273         if ( !count( $allpages ) ) {
00274             $out->addWikiMsg( 'tpt-list-nopages' );
00275 
00276             return;
00277         }
00278         $types = $this->classifyPages( $allpages );
00279 
00280         $pages = $types['proposed'];
00281         if ( count( $pages ) ) {
00282             $out->wrapWikiMsg( '== $1 ==', 'tpt-new-pages-title' );
00283             $out->addWikiMsg( 'tpt-new-pages', count( $pages ) );
00284             $out->addHtml( '<ol>' );
00285             foreach ( $pages as $page ) {
00286                 $link = Linker::link( $page['title'] );
00287                 $acts = $this->actionLinks( $page, 'proposed' );
00288                 $out->addHtml( "<li>$link $acts</li>" );
00289             }
00290             $out->addHtml( '</ol>' );
00291         }
00292 
00293         $pages = $types['active'];
00294         if ( count( $pages ) ) {
00295             $out->wrapWikiMsg( '== $1 ==', 'tpt-old-pages-title' );
00296             $out->addWikiMsg( 'tpt-old-pages', count( $pages ) );
00297             $out->addHtml( '<ol>' );
00298             foreach ( $pages as $page ) {
00299                 $link = Linker::link( $page['title'] );
00300                 if ( $page['tp:mark'] !== $page['tp:tag'] ) {
00301                     $link = "<strong>$link</strong>";
00302                 }
00303 
00304                 $acts = $this->actionLinks( $page, 'active' );
00305                 $out->addHtml( "<li>$link $acts</li>" );
00306             }
00307             $out->addHtml( '</ol>' );
00308         }
00309 
00310         $pages = $types['broken'];
00311         if ( count( $pages ) ) {
00312             $out->wrapWikiMsg( '== $1 ==', 'tpt-other-pages-title' );
00313             $out->addWikiMsg( 'tpt-other-pages', count( $pages ) );
00314             $out->addHtml( '<ol>' );
00315             foreach ( $pages as $page ) {
00316                 $link = Linker::link( $page['title'] );
00317                 $acts = $this->actionLinks( $page, 'broken' );
00318                 $out->addHtml( "<li>$link $acts</li>" );
00319             }
00320             $out->addHtml( '</ol>' );
00321         }
00322 
00323         $pages = $types['discouraged'];
00324         if ( count( $pages ) ) {
00325             $out->wrapWikiMsg( '== $1 ==', 'tpt-discouraged-pages-title' );
00326             $out->addWikiMsg( 'tpt-discouraged-pages', count( $pages ) );
00327             $out->addHtml( '<ol>' );
00328             foreach ( $pages as $page ) {
00329                 $link = Linker::link( $page['title'] );
00330                 if ( $page['tp:mark'] !== $page['tp:tag'] ) {
00331                     $link = "<strong>$link</strong>";
00332                 }
00333 
00334                 $acts = $this->actionLinks( $page, 'discouraged' );
00335                 $out->addHtml( "<li>$link $acts</li>" );
00336             }
00337             $out->addHtml( '</ol>' );
00338         }
00339     }
00340 
00346     protected function actionLinks( array $page, $type ) {
00347         $actions = array();
00351         $title = $page['title'];
00352         $user = $this->getUser();
00353 
00354         if ( $user->isAllowed( 'pagetranslation' ) ) {
00355             $token = $user->getEditToken();
00356 
00357             $pending = $type === 'active' && $page['latest'] !== $page['tp:mark'];
00358             if ( $type === 'proposed' || $pending ) {
00359                 $actions[] = Linker::link(
00360                     $this->getTitle(),
00361                     $this->msg( 'tpt-rev-mark' )->escaped(),
00362                     array( 'title' => $this->msg( 'tpt-rev-mark-tooltip' )->text() ),
00363                     array(
00364                         'do' => 'mark',
00365                         'target' => $title->getPrefixedText(),
00366                         'revision' => $title->getLatestRevId(),
00367                         'token' => $token,
00368                     )
00369                 );
00370             } elseif ( $type === 'broken' ) {
00371                 $actions[] = Linker::link(
00372                     $this->getTitle(),
00373                     $this->msg( 'tpt-rev-unmark' )->escaped(),
00374                     array( 'title' => $this->msg( 'tpt-rev-unmark-tooltip' )->text() ),
00375                     array(
00376                         'do' => 'unmark',
00377                         'target' => $title->getPrefixedText(),
00378                         'revision' => -1,
00379                         'token' => $token,
00380                     )
00381                 );
00382             }
00383 
00384             if ( $type === 'active' ) {
00385                 $actions[] = Linker::link(
00386                     $this->getTitle(),
00387                     $this->msg( 'tpt-rev-discourage' )->escaped(),
00388                     array( 'title' => $this->msg( 'tpt-rev-discourage-tooltip' )->text() ),
00389                     array(
00390                         'do' => 'discourage',
00391                         'target' => $title->getPrefixedText(),
00392                         'revision' => -1,
00393                         'token' => $token,
00394                     )
00395                 );
00396             } elseif ( $type === 'discouraged' ) {
00397                 $actions[] = Linker::link(
00398                     $this->getTitle(),
00399                     $this->msg( 'tpt-rev-encourage' )->escaped(),
00400                     array( 'title' => $this->msg( 'tpt-rev-encourage-tooltip' )->text() ),
00401                     array(
00402                         'do' => 'encourage',
00403                         'target' => $title->getPrefixedText(),
00404                         'revision' => -1,
00405                         'token' => $token,
00406                     )
00407                 );
00408             }
00409         }
00410 
00411         if ( !count( $actions ) ) {
00412             return '';
00413         }
00414 
00415         $flattened = $this->getLanguage()->semicolonList( $actions );
00416 
00417         return Html::rawElement(
00418             'span',
00419             array( 'class' => 'mw-tpt-actions' ),
00420             $this->msg( 'parentheses' )->rawParams( $flattened )->escaped()
00421         );
00422     }
00423 
00429     public function checkInput( TranslatablePage $page, &$error = false ) {
00430         $usedNames = array();
00431         $highest = intval( TranslateMetadata::get( $page->getMessageGroupId(), 'maxid' ) );
00432         $parse = $page->getParse();
00433         $sections = $parse->getSectionsForSave( $highest );
00434 
00435         foreach ( $sections as $s ) {
00436             // We need to do checks for both new and existing sections.
00437             // Someone might have tampered with the page source adding
00438             // duplicate or invalid markers.
00439             if ( isset( $usedNames[$s->id] ) ) {
00440                 $this->getOutput()->addWikiMsg( 'tpt-duplicate', $s->id );
00441                 $error = true;
00442             }
00443             $usedNames[$s->id] = true;
00444             $s->name = $s->id;
00445         }
00446 
00447         return $sections;
00448     }
00449 
00455     public function showPage( TranslatablePage $page, array $sections ) {
00456         global $wgContLang;
00457 
00458         $out = $this->getOutput();
00459 
00460         $out->setSubtitle( Linker::link( $page->getTitle() ) );
00461         $out->addModules( 'ext.translate.special.pagetranslation' );
00462 
00463         $out->addWikiMsg( 'tpt-showpage-intro' );
00464 
00465         $formParams = array(
00466             'method' => 'post',
00467             'action' => $this->getTitle()->getFullURL(),
00468             'class' => 'mw-tpt-sp-markform',
00469         );
00470 
00471         $out->addHTML(
00472             Xml::openElement( 'form', $formParams ) .
00473             Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
00474             Html::hidden( 'revision', $page->getRevision() ) .
00475             Html::hidden( 'target', $page->getTitle()->getPrefixedtext() ) .
00476             Html::hidden( 'token', $this->getUser()->getEditToken() )
00477         );
00478 
00479         $out->wrapWikiMsg( '==$1==', 'tpt-sections-oldnew' );
00480 
00481         $diffOld = $this->msg( 'tpt-diff-old' )->escaped();
00482         $diffNew = $this->msg( 'tpt-diff-new' )->escaped();
00483 
00487         foreach ( $sections as $s ) {
00488             if ( $s->type === 'new' ) {
00489                 $name = $this->msg( 'tpt-section-new', $s->name )->escaped();
00490             } else {
00491                 $name = $this->msg( 'tpt-section', $s->name )->escaped();
00492             }
00493 
00494             if ( $s->type === 'changed' ) {
00495                 $diff = new DifferenceEngine;
00496                 if ( method_exists( 'DifferenceEngine', 'setTextLanguage' ) ) {
00497                     $diff->setTextLanguage( $wgContLang );
00498                 }
00499                 $diff->setReducedLineNumbers();
00500                 $diff->setText( $s->getOldText(), $s->getText() );
00501                 $text = $diff->getDiff( $diffOld, $diffNew );
00502                 $diffOld = $diffNew = null;
00503                 $diff->showDiffStyle();
00504 
00505                 $id = "tpt-sect-{$s->id}-action-nofuzzy";
00506                 $checkLabel = Xml::checkLabel(
00507                     $this->msg( 'tpt-action-nofuzzy' )->text(),
00508                     $id,
00509                     $id,
00510                     false
00511                 );
00512                 $text = $checkLabel . $text;
00513             } else {
00514                 $text = TranslateUtils::convertWhiteSpaceToHTML( $s->getText() );
00515             }
00516 
00517             # For changed text, the language is set by $diff->setTextLanguage()
00518             $lang = $s->type === 'changed' ? null : $wgContLang;
00519             $out->addHTML( MessageWebImporter::makeSectionElement(
00520                 $name,
00521                 $s->type,
00522                 $text, $lang
00523             ) );
00524         }
00525 
00526         $deletedSections = $page->getParse()->getDeletedSections();
00527         if ( count( $deletedSections ) ) {
00528             $out->wrapWikiMsg( '==$1==', 'tpt-sections-deleted' );
00529 
00533             foreach ( $deletedSections as $s ) {
00534                 $name = $this->msg( 'tpt-section-deleted', $s->id )->escaped();
00535                 $text = TranslateUtils::convertWhiteSpaceToHTML( $s->getText() );
00536                 $out->addHTML( MessageWebImporter::makeSectionElement(
00537                     $name,
00538                     $s->type,
00539                     $text,
00540                     $wgContLang
00541                 ) );
00542             }
00543         }
00544 
00545         // Display template changes if applicable
00546         if ( $page->getMarkedTag() !== false ) {
00547             $newTemplate = $page->getParse()->getTemplatePretty();
00548             $oldPage = TranslatablePage::newFromRevision(
00549                 $page->getTitle(),
00550                 $page->getMarkedTag()
00551             );
00552             $oldTemplate = $oldPage->getParse()->getTemplatePretty();
00553 
00554             if ( $oldTemplate !== $newTemplate ) {
00555                 $out->wrapWikiMsg( '==$1==', 'tpt-sections-template' );
00556 
00557                 $diff = new DifferenceEngine;
00558                 if ( method_exists( 'DifferenceEngine', 'setTextLanguage' ) ) {
00559                     $diff->setTextLanguage( $wgContLang );
00560                 }
00561                 $diff->setText( $oldTemplate, $newTemplate );
00562                 $text = $diff->getDiff(
00563                     $this->msg( 'tpt-diff-old' )->escaped(),
00564                     $this->msg( 'tpt-diff-new' )->escaped()
00565                 );
00566                 $diff->showDiffStyle();
00567                 $diff->setReducedLineNumbers();
00568 
00569                 $contentParams = array( 'class' => 'mw-tpt-sp-content' );
00570                 $out->addHTML( Xml::tags( 'div', $contentParams, $text ) );
00571             }
00572         }
00573 
00574         $this->priorityLanguagesForm( $page );
00575 
00576         $out->addHTML(
00577             Xml::submitButton( $this->msg( 'tpt-submit' )->text() ) .
00578             Xml::closeElement( 'form' )
00579         );
00580     }
00581 
00585     protected function priorityLanguagesForm( TranslatablePage $page ) {
00586         global $wgContLang;
00587 
00588         $groupId = $page->getMessageGroupId();
00589         $this->getOutput()->wrapWikiMsg( '==$1==', 'tpt-sections-prioritylangs' );
00590 
00591         $langSelector = Xml::languageSelector(
00592             $wgContLang->getCode(),
00593             false,
00594             $this->getLanguage()->getCode()
00595         );
00596 
00597         $hLangs = Xml::inputLabelSep(
00598             $this->msg( 'tpt-select-prioritylangs' )->text(),
00599             'prioritylangs', // name
00600             'tpt-prioritylangs', // id
00601             50,
00602             TranslateMetadata::get( $groupId, 'prioritylangs' )
00603         );
00604 
00605         $hForce = Xml::checkLabel(
00606             $this->msg( 'tpt-select-prioritylangs-force' )->text(),
00607             'forcelimit', // name
00608             'tpt-priority-forcelimit', // id
00609             TranslateMetadata::get( $groupId, 'priorityforce' ) === 'on'
00610         );
00611 
00612         $hReason = Xml::inputLabelSep(
00613             $this->msg( 'tpt-select-prioritylangs-reason' )->text(),
00614             'priorityreason', // name
00615             'tpt-priority-reason', // id
00616             50, // size
00617             TranslateMetadata::get( $groupId, 'priorityreason' )
00618         );
00619 
00620         $this->getOutput()->addHTML(
00621             "<table>" .
00622             "<tr>" .
00623             "<td class='mw-label'>$hLangs[0]</td>" .
00624             "<td class='mw-input'>$hLangs[1]$langSelector[1]</td>" .
00625             "</tr>" .
00626             "<tr><td></td><td class='mw-inout'>$hForce</td></tr>" .
00627             "<tr>" .
00628             "<td class='mw-label'>$hReason[0]</td>" .
00629             "<td class='mw-input'>$hReason[1]</td>" .
00630             "</tr>" .
00631             "</table>"
00632         );
00633     }
00634 
00646     public function markForTranslation( TranslatablePage $page, array $sections ) {
00647         // Add the section markers to the source page
00648         $wikiPage = WikiPage::factory( $page->getTitle() );
00649         $status = $wikiPage->doEdit(
00650             $page->getParse()->getSourcePageText(), // Content
00651             $this->msg( 'tpt-mark-summary' )->inContentLanguage()->text(), // Summary
00652             EDIT_FORCE_BOT | EDIT_UPDATE // Flags
00653         );
00654 
00655         if ( !$status->isOK() ) {
00656             return array( 'tpt-edit-failed', $status->getWikiText() );
00657         }
00658 
00659         $newrevision = $status->value['revision'];
00660 
00661         // In theory it is either null or Revision object,
00662         // never revision object with null id, but who knows
00663         if ( $newrevision instanceof Revision ) {
00664             $newrevision = $newrevision->getId();
00665         }
00666 
00667         if ( $newrevision === null ) {
00668             // Probably a no-change edit, so no new revision was assigned.
00669             // Get the latest revision manually
00670             $newrevision = $page->getTitle()->getLatestRevId();
00671         }
00672 
00673         $inserts = array();
00674         $changed = array();
00675         $maxid = intval( TranslateMetadata::get( $page->getMessageGroupId(), 'maxid' ) );
00676 
00677         $pageId = $page->getTitle()->getArticleID();
00681         foreach ( array_values( $sections ) as $index => $s ) {
00682             $maxid = max( $maxid, intval( $s->name ) );
00683             $changed[] = $s->name;
00684 
00685             if ( $this->getRequest()->getCheck( "tpt-sect-{$s->id}-action-nofuzzy" ) ) {
00686                 // This will be checked by getTranslationUnitJobs
00687                 $s->type = 'old';
00688             }
00689 
00690             $inserts[] = array(
00691                 'trs_page' => $pageId,
00692                 'trs_key' => $s->name,
00693                 'trs_text' => $s->getText(),
00694                 'trs_order' => $index
00695             );
00696         }
00697 
00698         $dbw = wfGetDB( DB_MASTER );
00699         $dbw->delete(
00700             'translate_sections',
00701             array( 'trs_page' => $page->getTitle()->getArticleID() ),
00702             __METHOD__
00703         );
00704         $dbw->insert( 'translate_sections', $inserts, __METHOD__ );
00705         TranslateMetadata::set( $page->getMessageGroupId(), 'maxid', $maxid );
00706 
00707         $page->addMarkedTag( $newrevision );
00708         MessageGroups::clearCache();
00709 
00710         $jobs = self::getRenderJobs( $page );
00711         Job::batchInsert( $jobs );
00712 
00713         $jobs = self::getTranslationUnitJobs( $page, $sections );
00714         Job::batchInsert( $jobs );
00715 
00716         // Logging
00717         $this->handlePriorityLanguages( $this->getRequest(), $page );
00718 
00719         $entry = new ManualLogEntry( 'pagetranslation', 'mark' );
00720         $entry->setPerformer( $this->getUser() );
00721         $entry->setTarget( $page->getTitle() );
00722         $entry->setParameters( array(
00723             'revision' => $newrevision,
00724             'changed' => count( $changed ),
00725         ) );
00726         $logid = $entry->insert();
00727         $entry->publish( $logid );
00728 
00729         // Clear more caches
00730         $page->getTitle()->invalidateCache();
00731         MessageIndexRebuildJob::newJob()->run();
00732 
00733         return false;
00734     }
00735 
00740     protected function handlePriorityLanguages( WebRequest $request, TranslatablePage $page ) {
00741         // new priority languages
00742         $npLangs = rtrim( trim( $request->getVal( 'prioritylangs' ) ), ',' );
00743         $npForce = $request->getCheck( 'forcelimit' ) ? 'on' : 'off';
00744         $npReason = trim( $request->getText( 'priorityreason' ) );
00745 
00746         // Normalize
00747         $npLangs = array_map( 'trim', explode( ',', $npLangs ) );
00748         $npLangs = array_unique( $npLangs );
00749         // Remove invalid language codes.
00750         $languages = Language::getLanguageNames();
00751         foreach ( $npLangs as $index => $language ) {
00752             if ( !array_key_exists( $language, $languages ) ) {
00753                 unset( $npLangs[$index] );
00754             }
00755         }
00756         $npLangs = implode( ',', $npLangs );
00757         if ( $npLangs === '' ) {
00758             $npLangs = false;
00759             $npForce = false;
00760             $npReason = false;
00761         }
00762 
00763         $groupId = $page->getMessageGroupId();
00764         // old priority languages
00765         $opLangs = TranslateMetadata::get( $groupId, 'prioritylangs' );
00766         $opForce = TranslateMetadata::get( $groupId, 'priorityforce' );
00767         $opReason = TranslateMetadata::get( $groupId, 'priorityreason' );
00768 
00769         TranslateMetadata::set( $groupId, 'prioritylangs', $npLangs );
00770         TranslateMetadata::set( $groupId, 'priorityforce', $npForce );
00771         TranslateMetadata::set( $groupId, 'priorityreason', $npReason );
00772 
00773         if ( $opLangs !== $npLangs || $opForce !== $npForce || $opReason !== $npReason ) {
00774             $params = array(
00775                 'languages' => $npLangs,
00776                 'force' => $npForce,
00777                 'reason' => $npReason,
00778             );
00779 
00780             $entry = new ManualLogEntry( 'pagetranslation', 'prioritylanguages' );
00781             $entry->setPerformer( $this->getUser() );
00782             $entry->setTarget( $page->getTitle() );
00783             $entry->setParameters( $params );
00784             $entry->setComment( $npReason );
00785             $logid = $entry->insert();
00786             $entry->publish( $logid );
00787         }
00788     }
00789 
00796     public static function getRenderJobs( TranslatablePage $page ) {
00797         $jobs = array();
00798 
00799         $titles = $page->getTranslationPages();
00800         foreach ( $titles as $t ) {
00801             $jobs[] = TranslateRenderJob::newJob( $t );
00802         }
00803 
00804         return $jobs;
00805     }
00806 
00814     public static function getTranslationUnitJobs( TranslatablePage $page, array $sections ) {
00815         $jobs = array();
00816 
00817         $code = $page->getSourceLanguageCode();
00818         $prefix = $page->getTitle()->getPrefixedText();
00819 
00820         foreach ( $sections as $s ) {
00821             $unit = $s->name;
00822             $title = Title::makeTitle( NS_TRANSLATIONS, "$prefix/$unit/$code" );
00823 
00824             $fuzzy = $s->type === 'changed';
00825             $jobs[] = MessageUpdateJob::newJob( $title, $s->text, $fuzzy );
00826         }
00827 
00828         return $jobs;
00829     }
00830 }
Generated on Tue Oct 29 00:00:24 2013 for MediaWiki Translate Extension by  doxygen 1.6.3