MediaWiki
REL1_20
|
00001 <?php 00029 class MovePageForm extends UnlistedSpecialPage { 00030 00034 var $oldTitle, $newTitle; # Objects 00035 var $reason; # Text input 00036 var $moveTalk, $deleteAndMove, $moveSubpages, $fixRedirects, $leaveRedirect, $moveOverShared; # Checks 00037 00038 private $watch = false; 00039 00040 public function __construct() { 00041 parent::__construct( 'Movepage' ); 00042 } 00043 00044 public function execute( $par ) { 00045 $this->checkReadOnly(); 00046 00047 $this->setHeaders(); 00048 $this->outputHeader(); 00049 00050 $request = $this->getRequest(); 00051 $target = !is_null( $par ) ? $par : $request->getVal( 'target' ); 00052 00053 // Yes, the use of getVal() and getText() is wanted, see bug 20365 00054 00055 $oldTitleText = $request->getVal( 'wpOldTitle', $target ); 00056 $this->oldTitle = Title::newFromText( $oldTitleText ); 00057 00058 if( is_null( $this->oldTitle ) ) { 00059 throw new ErrorPageError( 'notargettitle', 'notargettext' ); 00060 } 00061 if( !$this->oldTitle->exists() ) { 00062 throw new ErrorPageError( 'nopagetitle', 'nopagetext' ); 00063 } 00064 00065 $newTitleTextMain = $request->getText( 'wpNewTitleMain' ); 00066 $newTitleTextNs = $request->getInt( 'wpNewTitleNs', $this->oldTitle->getNamespace() ); 00067 // Backwards compatibility for forms submitting here from other sources 00068 // which is more common than it should be.. 00069 $newTitleText_bc = $request->getText( 'wpNewTitle' ); 00070 $this->newTitle = strlen( $newTitleText_bc ) > 0 00071 ? Title::newFromText( $newTitleText_bc ) 00072 : Title::makeTitleSafe( $newTitleTextNs, $newTitleTextMain ); 00073 00074 00075 $user = $this->getUser(); 00076 00077 # Check rights 00078 $permErrors = $this->oldTitle->getUserPermissionsErrors( 'move', $user ); 00079 if ( count( $permErrors ) ) { 00080 // Auto-block user's IP if the account was "hard" blocked 00081 $user->spreadAnyEditBlock(); 00082 throw new PermissionsError( 'move', $permErrors ); 00083 } 00084 00085 $def = !$request->wasPosted(); 00086 00087 $this->reason = $request->getText( 'wpReason' ); 00088 $this->moveTalk = $request->getBool( 'wpMovetalk', $def ); 00089 $this->fixRedirects = $request->getBool( 'wpFixRedirects', $def ); 00090 $this->leaveRedirect = $request->getBool( 'wpLeaveRedirect', $def ); 00091 $this->moveSubpages = $request->getBool( 'wpMovesubpages', false ); 00092 $this->deleteAndMove = $request->getBool( 'wpDeleteAndMove' ) && $request->getBool( 'wpConfirm' ); 00093 $this->moveOverShared = $request->getBool( 'wpMoveOverSharedFile', false ); 00094 $this->watch = $request->getCheck( 'wpWatch' ) && $user->isLoggedIn(); 00095 00096 if ( 'submit' == $request->getVal( 'action' ) && $request->wasPosted() 00097 && $user->matchEditToken( $request->getVal( 'wpEditToken' ) ) ) { 00098 $this->doSubmit(); 00099 } else { 00100 $this->showForm( array() ); 00101 } 00102 } 00103 00111 function showForm( $err ) { 00112 global $wgContLang, $wgFixDoubleRedirects, $wgMaximumMovedPages; 00113 00114 $this->getSkin()->setRelevantTitle( $this->oldTitle ); 00115 00116 $oldTitleLink = Linker::link( $this->oldTitle ); 00117 00118 $out = $this->getOutput(); 00119 $out->setPageTitle( $this->msg( 'move-page', $this->oldTitle->getPrefixedText() ) ); 00120 $out->addModules( 'mediawiki.special.movePage' ); 00121 00122 $newTitle = $this->newTitle; 00123 00124 if ( !$newTitle ) { 00125 # Show the current title as a default 00126 # when the form is first opened. 00127 $newTitle = $this->oldTitle; 00128 } elseif ( !count( $err ) ) { 00129 # If a title was supplied, probably from the move log revert 00130 # link, check for validity. We can then show some diagnostic 00131 # information and save a click. 00132 $newerr = $this->oldTitle->isValidMoveOperation( $newTitle ); 00133 if( is_array( $newerr ) ) { 00134 $err = $newerr; 00135 } 00136 } 00137 00138 $user = $this->getUser(); 00139 00140 if ( count( $err ) == 1 && isset( $err[0][0] ) && $err[0][0] == 'articleexists' 00141 && $newTitle->quickUserCan( 'delete', $user ) 00142 ) { 00143 $out->addWikiMsg( 'delete_and_move_text', $newTitle->getPrefixedText() ); 00144 $movepagebtn = $this->msg( 'delete_and_move' )->text(); 00145 $submitVar = 'wpDeleteAndMove'; 00146 $confirm = " 00147 <tr> 00148 <td></td> 00149 <td class='mw-input'>" . 00150 Xml::checkLabel( $this->msg( 'delete_and_move_confirm' )->text(), 'wpConfirm', 'wpConfirm' ) . 00151 "</td> 00152 </tr>"; 00153 $err = array(); 00154 } else { 00155 if ($this->oldTitle->getNamespace() == NS_USER && !$this->oldTitle->isSubpage() ) { 00156 $out->wrapWikiMsg( "<div class=\"error mw-moveuserpage-warning\">\n$1\n</div>", 'moveuserpage-warning' ); 00157 } 00158 $out->addWikiMsg( $wgFixDoubleRedirects ? 'movepagetext' : 00159 'movepagetext-noredirectfixer' ); 00160 $movepagebtn = $this->msg( 'movepagebtn' )->text(); 00161 $submitVar = 'wpMove'; 00162 $confirm = false; 00163 } 00164 00165 if ( count( $err ) == 1 && isset( $err[0][0] ) && $err[0][0] == 'file-exists-sharedrepo' 00166 && $user->isAllowed( 'reupload-shared' ) 00167 ) { 00168 $out->addWikiMsg( 'move-over-sharedrepo', $newTitle->getPrefixedText() ); 00169 $submitVar = 'wpMoveOverSharedFile'; 00170 $err = array(); 00171 } 00172 00173 $oldTalk = $this->oldTitle->getTalkPage(); 00174 $oldTitleSubpages = $this->oldTitle->hasSubpages(); 00175 $oldTitleTalkSubpages = $this->oldTitle->getTalkPage()->hasSubpages(); 00176 00177 $canMoveSubpage = ( $oldTitleSubpages || $oldTitleTalkSubpages ) && 00178 !count( $this->oldTitle->getUserPermissionsErrors( 'move-subpages', $user ) ); 00179 00180 # We also want to be able to move assoc. subpage talk-pages even if base page 00181 # has no associated talk page, so || with $oldTitleTalkSubpages. 00182 $considerTalk = !$this->oldTitle->isTalkPage() && 00183 ( $oldTalk->exists() 00184 || ( $oldTitleTalkSubpages && $canMoveSubpage ) ); 00185 00186 $dbr = wfGetDB( DB_SLAVE ); 00187 if ( $wgFixDoubleRedirects ) { 00188 $hasRedirects = $dbr->selectField( 'redirect', '1', 00189 array( 00190 'rd_namespace' => $this->oldTitle->getNamespace(), 00191 'rd_title' => $this->oldTitle->getDBkey(), 00192 ) , __METHOD__ ); 00193 } else { 00194 $hasRedirects = false; 00195 } 00196 00197 if ( $considerTalk ) { 00198 $out->addWikiMsg( 'movepagetalktext' ); 00199 } 00200 00201 if ( count( $err ) ) { 00202 $out->addHTML( "<div class='error'>\n" ); 00203 $action_desc = $this->msg( 'action-move' )->plain(); 00204 $out->addWikiMsg( 'permissionserrorstext-withaction', count( $err ), $action_desc ); 00205 00206 if ( count( $err ) == 1 ) { 00207 $errMsg = $err[0]; 00208 $errMsgName = array_shift( $errMsg ); 00209 if ( $errMsgName == 'hookaborted' ) { 00210 $out->addHTML( "<p>{$errMsg[0]}</p>\n" ); 00211 } else { 00212 $out->addWikiMsgArray( $errMsgName, $errMsg ); 00213 } 00214 } else { 00215 $errStr = array(); 00216 foreach( $err as $errMsg ) { 00217 if( $errMsg[0] == 'hookaborted' ) { 00218 $errStr[] = $errMsg[1]; 00219 } else { 00220 $errMsgName = array_shift( $errMsg ); 00221 $errStr[] = $this->msg( $errMsgName, $errMsg )->parse(); 00222 } 00223 } 00224 00225 $out->addHTML( '<ul><li>' . implode( "</li>\n<li>", $errStr ) . "</li></ul>\n" ); 00226 } 00227 $out->addHTML( "</div>\n" ); 00228 } 00229 00230 if ( $this->oldTitle->isProtected( 'move' ) ) { 00231 # Is the title semi-protected? 00232 if ( $this->oldTitle->isSemiProtected( 'move' ) ) { 00233 $noticeMsg = 'semiprotectedpagemovewarning'; 00234 $classes[] = 'mw-textarea-sprotected'; 00235 } else { 00236 # Then it must be protected based on static groups (regular) 00237 $noticeMsg = 'protectedpagemovewarning'; 00238 $classes[] = 'mw-textarea-protected'; 00239 } 00240 $out->addHTML( "<div class='mw-warning-with-logexcerpt'>\n" ); 00241 $out->addWikiMsg( $noticeMsg ); 00242 LogEventsList::showLogExtract( $out, 'protect', $this->oldTitle, '', array( 'lim' => 1 ) ); 00243 $out->addHTML( "</div>\n" ); 00244 } 00245 00246 // Byte limit (not string length limit) for wpReason and wpNewTitleMain 00247 // is enforced in the mediawiki.special.movePage module 00248 00249 $immovableNamespaces = array(); 00250 00251 foreach ( array_keys( $this->getLanguage()->getNamespaces() ) as $nsId ) { 00252 if ( !MWNamespace::isMovable( $nsId ) ) { 00253 $immovableNamespaces[] = $nsId; 00254 } 00255 } 00256 00257 $out->addHTML( 00258 Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalURL( 'action=submit' ), 'id' => 'movepage' ) ) . 00259 Xml::openElement( 'fieldset' ) . 00260 Xml::element( 'legend', null, $this->msg( 'move-page-legend' )->text() ) . 00261 Xml::openElement( 'table', array( 'id' => 'mw-movepage-table' ) ) . 00262 "<tr> 00263 <td class='mw-label'>" . 00264 $this->msg( 'movearticle' )->escaped() . 00265 "</td> 00266 <td class='mw-input'> 00267 <strong>{$oldTitleLink}</strong> 00268 </td> 00269 </tr> 00270 <tr> 00271 <td class='mw-label'>" . 00272 Xml::label( $this->msg( 'newtitle' )->text(), 'wpNewTitleMain' ) . 00273 "</td> 00274 <td class='mw-input'>" . 00275 Html::namespaceSelector( 00276 array( 00277 'selected' => $newTitle->getNamespace(), 00278 'exclude' => $immovableNamespaces 00279 ), 00280 array( 'name' => 'wpNewTitleNs', 'id' => 'wpNewTitleNs' ) 00281 ) . 00282 Xml::input( 'wpNewTitleMain', 60, $wgContLang->recodeForEdit( $newTitle->getText() ), array( 00283 'type' => 'text', 00284 'id' => 'wpNewTitleMain', 00285 'maxlength' => 255, 00286 ) ) . 00287 Html::hidden( 'wpOldTitle', $this->oldTitle->getPrefixedText() ) . 00288 "</td> 00289 </tr> 00290 <tr> 00291 <td class='mw-label'>" . 00292 Xml::label( $this->msg( 'movereason' )->text(), 'wpReason' ) . 00293 "</td> 00294 <td class='mw-input'>" . 00295 Html::element( 'textarea', array( 'name' => 'wpReason', 'id' => 'wpReason', 'cols' => 60, 'rows' => 2, 00296 'maxlength' => 200 ), $this->reason ) . 00297 "</td> 00298 </tr>" 00299 ); 00300 00301 if( $considerTalk ) { 00302 $out->addHTML( " 00303 <tr> 00304 <td></td> 00305 <td class='mw-input'>" . 00306 Xml::checkLabel( $this->msg( 'movetalk' )->text(), 'wpMovetalk', 'wpMovetalk', $this->moveTalk ) . 00307 "</td> 00308 </tr>" 00309 ); 00310 } 00311 00312 if ( $user->isAllowed( 'suppressredirect' ) ) { 00313 $out->addHTML( " 00314 <tr> 00315 <td></td> 00316 <td class='mw-input' >" . 00317 Xml::checkLabel( $this->msg( 'move-leave-redirect' )->text(), 'wpLeaveRedirect', 00318 'wpLeaveRedirect', $this->leaveRedirect ) . 00319 "</td> 00320 </tr>" 00321 ); 00322 } 00323 00324 if ( $hasRedirects ) { 00325 $out->addHTML( " 00326 <tr> 00327 <td></td> 00328 <td class='mw-input' >" . 00329 Xml::checkLabel( $this->msg( 'fix-double-redirects' )->text(), 'wpFixRedirects', 00330 'wpFixRedirects', $this->fixRedirects ) . 00331 "</td> 00332 </tr>" 00333 ); 00334 } 00335 00336 if( $canMoveSubpage ) { 00337 $out->addHTML( " 00338 <tr> 00339 <td></td> 00340 <td class=\"mw-input\">" . 00341 Xml::check( 00342 'wpMovesubpages', 00343 # Don't check the box if we only have talk subpages to 00344 # move and we aren't moving the talk page. 00345 $this->moveSubpages && ($this->oldTitle->hasSubpages() || $this->moveTalk), 00346 array( 'id' => 'wpMovesubpages' ) 00347 ) . ' ' . 00348 Xml::tags( 'label', array( 'for' => 'wpMovesubpages' ), 00349 $this->msg( 00350 ( $this->oldTitle->hasSubpages() 00351 ? 'move-subpages' 00352 : 'move-talk-subpages' ) 00353 )->numParams( $wgMaximumMovedPages )->params( $wgMaximumMovedPages )->parse() 00354 ) . 00355 "</td> 00356 </tr>" 00357 ); 00358 } 00359 00360 $watchChecked = $user->isLoggedIn() && ($this->watch || $user->getBoolOption( 'watchmoves' ) 00361 || $user->isWatched( $this->oldTitle ) ); 00362 # Don't allow watching if user is not logged in 00363 if( $user->isLoggedIn() ) { 00364 $out->addHTML( " 00365 <tr> 00366 <td></td> 00367 <td class='mw-input'>" . 00368 Xml::checkLabel( $this->msg( 'move-watch' )->text(), 'wpWatch', 'watch', $watchChecked ) . 00369 "</td> 00370 </tr>"); 00371 } 00372 00373 $out->addHTML( " 00374 {$confirm} 00375 <tr> 00376 <td> </td> 00377 <td class='mw-submit'>" . 00378 Xml::submitButton( $movepagebtn, array( 'name' => $submitVar ) ) . 00379 "</td> 00380 </tr>" . 00381 Xml::closeElement( 'table' ) . 00382 Html::hidden( 'wpEditToken', $user->getEditToken() ) . 00383 Xml::closeElement( 'fieldset' ) . 00384 Xml::closeElement( 'form' ) . 00385 "\n" 00386 ); 00387 00388 $this->showLogFragment( $this->oldTitle ); 00389 $this->showSubpages( $this->oldTitle ); 00390 00391 } 00392 00393 function doSubmit() { 00394 global $wgMaximumMovedPages, $wgFixDoubleRedirects; 00395 00396 $user = $this->getUser(); 00397 00398 if ( $user->pingLimiter( 'move' ) ) { 00399 throw new ThrottledError; 00400 } 00401 00402 $ot = $this->oldTitle; 00403 $nt = $this->newTitle; 00404 00405 # don't allow moving to pages with # in 00406 if ( !$nt || $nt->getFragment() != '' ) { 00407 $this->showForm( array( array( 'badtitletext' ) ) ); 00408 return; 00409 } 00410 00411 # Show a warning if the target file exists on a shared repo 00412 if ( $nt->getNamespace() == NS_FILE 00413 && !( $this->moveOverShared && $user->isAllowed( 'reupload-shared' ) ) 00414 && !RepoGroup::singleton()->getLocalRepo()->findFile( $nt ) 00415 && wfFindFile( $nt ) ) 00416 { 00417 $this->showForm( array( array( 'file-exists-sharedrepo' ) ) ); 00418 return; 00419 00420 } 00421 00422 # Delete to make way if requested 00423 if ( $this->deleteAndMove ) { 00424 $permErrors = $nt->getUserPermissionsErrors( 'delete', $user ); 00425 if ( count( $permErrors ) ) { 00426 # Only show the first error 00427 $this->showForm( $permErrors ); 00428 return; 00429 } 00430 00431 $reason = $this->msg( 'delete_and_move_reason', $ot )->inContentLanguage()->text(); 00432 00433 // Delete an associated image if there is 00434 if ( $nt->getNamespace() == NS_FILE ) { 00435 $file = wfLocalFile( $nt ); 00436 if ( $file->exists() ) { 00437 $file->delete( $reason, false ); 00438 } 00439 } 00440 00441 $error = ''; // passed by ref 00442 $page = WikiPage::factory( $nt ); 00443 $deleteStatus = $page->doDeleteArticleReal( $reason, false, 0, true, $error, $user ); 00444 if ( !$deleteStatus->isGood() ) { 00445 $this->showForm( $deleteStatus->getErrorsArray() ); 00446 return; 00447 } 00448 } 00449 00450 if ( $user->isAllowed( 'suppressredirect' ) ) { 00451 $createRedirect = $this->leaveRedirect; 00452 } else { 00453 $createRedirect = true; 00454 } 00455 00456 # Do the actual move. 00457 $error = $ot->moveTo( $nt, true, $this->reason, $createRedirect ); 00458 if ( $error !== true ) { 00459 $this->showForm( $error ); 00460 return; 00461 } 00462 00463 if ( $wgFixDoubleRedirects && $this->fixRedirects ) { 00464 DoubleRedirectJob::fixRedirects( 'move', $ot, $nt ); 00465 } 00466 00467 wfRunHooks( 'SpecialMovepageAfterMove', array( &$this, &$ot, &$nt ) ); 00468 00469 $out = $this->getOutput(); 00470 $out->setPageTitle( $this->msg( 'pagemovedsub' ) ); 00471 00472 $oldLink = Linker::link( 00473 $ot, 00474 null, 00475 array(), 00476 array( 'redirect' => 'no' ) 00477 ); 00478 $newLink = Linker::linkKnown( $nt ); 00479 $oldText = $ot->getPrefixedText(); 00480 $newText = $nt->getPrefixedText(); 00481 00482 $msgName = $createRedirect ? 'movepage-moved-redirect' : 'movepage-moved-noredirect'; 00483 $out->addHTML( $this->msg( 'movepage-moved' )->rawParams( $oldLink, 00484 $newLink )->params( $oldText, $newText )->parseAsBlock() ); 00485 $out->addWikiMsg( $msgName ); 00486 00487 # Now we move extra pages we've been asked to move: subpages and talk 00488 # pages. First, if the old page or the new page is a talk page, we 00489 # can't move any talk pages: cancel that. 00490 if( $ot->isTalkPage() || $nt->isTalkPage() ) { 00491 $this->moveTalk = false; 00492 } 00493 00494 if ( count( $ot->getUserPermissionsErrors( 'move-subpages', $user ) ) ) { 00495 $this->moveSubpages = false; 00496 } 00497 00498 # Next make a list of id's. This might be marginally less efficient 00499 # than a more direct method, but this is not a highly performance-cri- 00500 # tical code path and readable code is more important here. 00501 # 00502 # Note: this query works nicely on MySQL 5, but the optimizer in MySQL 00503 # 4 might get confused. If so, consider rewriting as a UNION. 00504 # 00505 # If the target namespace doesn't allow subpages, moving with subpages 00506 # would mean that you couldn't move them back in one operation, which 00507 # is bad. 00508 # @todo FIXME: A specific error message should be given in this case. 00509 00510 // @todo FIXME: Use Title::moveSubpages() here 00511 $dbr = wfGetDB( DB_MASTER ); 00512 if( $this->moveSubpages && ( 00513 MWNamespace::hasSubpages( $nt->getNamespace() ) || ( 00514 $this->moveTalk && 00515 MWNamespace::hasSubpages( $nt->getTalkPage()->getNamespace() ) 00516 ) 00517 ) ) { 00518 $conds = array( 00519 'page_title' . $dbr->buildLike( $ot->getDBkey() . '/', $dbr->anyString() ) 00520 .' OR page_title = ' . $dbr->addQuotes( $ot->getDBkey() ) 00521 ); 00522 $conds['page_namespace'] = array(); 00523 if( MWNamespace::hasSubpages( $nt->getNamespace() ) ) { 00524 $conds['page_namespace'] []= $ot->getNamespace(); 00525 } 00526 if( $this->moveTalk && MWNamespace::hasSubpages( $nt->getTalkPage()->getNamespace() ) ) { 00527 $conds['page_namespace'] []= $ot->getTalkPage()->getNamespace(); 00528 } 00529 } elseif( $this->moveTalk ) { 00530 $conds = array( 00531 'page_namespace' => $ot->getTalkPage()->getNamespace(), 00532 'page_title' => $ot->getDBkey() 00533 ); 00534 } else { 00535 # Skip the query 00536 $conds = null; 00537 } 00538 00539 $extraPages = array(); 00540 if( !is_null( $conds ) ) { 00541 $extraPages = TitleArray::newFromResult( 00542 $dbr->select( 'page', 00543 array( 'page_id', 'page_namespace', 'page_title' ), 00544 $conds, 00545 __METHOD__ 00546 ) 00547 ); 00548 } 00549 00550 $extraOutput = array(); 00551 $count = 1; 00552 foreach( $extraPages as $oldSubpage ) { 00553 if( $ot->equals( $oldSubpage ) ) { 00554 # Already did this one. 00555 continue; 00556 } 00557 00558 $newPageName = preg_replace( 00559 '#^'.preg_quote( $ot->getDBkey(), '#' ).'#', 00560 StringUtils::escapeRegexReplacement( $nt->getDBkey() ), # bug 21234 00561 $oldSubpage->getDBkey() 00562 ); 00563 if( $oldSubpage->isTalkPage() ) { 00564 $newNs = $nt->getTalkPage()->getNamespace(); 00565 } else { 00566 $newNs = $nt->getSubjectPage()->getNamespace(); 00567 } 00568 # Bug 14385: we need makeTitleSafe because the new page names may 00569 # be longer than 255 characters. 00570 $newSubpage = Title::makeTitleSafe( $newNs, $newPageName ); 00571 if( !$newSubpage ) { 00572 $oldLink = Linker::linkKnown( $oldSubpage ); 00573 $extraOutput []= $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink 00574 )->params( Title::makeName( $newNs, $newPageName ) )->escaped(); 00575 continue; 00576 } 00577 00578 # This was copy-pasted from Renameuser, bleh. 00579 if ( $newSubpage->exists() && !$oldSubpage->isValidMoveTarget( $newSubpage ) ) { 00580 $link = Linker::linkKnown( $newSubpage ); 00581 $extraOutput []= $this->msg( 'movepage-page-exists' )->rawParams( $link )->escaped(); 00582 } else { 00583 $success = $oldSubpage->moveTo( $newSubpage, true, $this->reason, $createRedirect ); 00584 if( $success === true ) { 00585 if ( $this->fixRedirects ) { 00586 DoubleRedirectJob::fixRedirects( 'move', $oldSubpage, $newSubpage ); 00587 } 00588 $oldLink = Linker::link( 00589 $oldSubpage, 00590 null, 00591 array(), 00592 array( 'redirect' => 'no' ) 00593 ); 00594 $newLink = Linker::linkKnown( $newSubpage ); 00595 $extraOutput []= $this->msg( 'movepage-page-moved' )->rawParams( $oldLink, $newLink )->escaped(); 00596 ++$count; 00597 if( $count >= $wgMaximumMovedPages ) { 00598 $extraOutput []= $this->msg( 'movepage-max-pages' )->numParams( $wgMaximumMovedPages )->escaped(); 00599 break; 00600 } 00601 } else { 00602 $oldLink = Linker::linkKnown( $oldSubpage ); 00603 $newLink = Linker::link( $newSubpage ); 00604 $extraOutput []= $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink, $newLink )->escaped(); 00605 } 00606 } 00607 00608 } 00609 00610 if( $extraOutput !== array() ) { 00611 $out->addHTML( "<ul>\n<li>" . implode( "</li>\n<li>", $extraOutput ) . "</li>\n</ul>" ); 00612 } 00613 00614 # Deal with watches (we don't watch subpages) 00615 if( $this->watch && $user->isLoggedIn() ) { 00616 $user->addWatch( $ot ); 00617 $user->addWatch( $nt ); 00618 } else { 00619 $user->removeWatch( $ot ); 00620 $user->removeWatch( $nt ); 00621 } 00622 00623 # Re-clear the file redirect cache, which may have been polluted by 00624 # parsing in messages above. See CR r56745. 00625 # @todo FIXME: Needs a more robust solution inside FileRepo. 00626 if( $ot->getNamespace() == NS_FILE ) { 00627 RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect( $ot ); 00628 } 00629 } 00630 00631 function showLogFragment( $title ) { 00632 $moveLogPage = new LogPage( 'move' ); 00633 $out = $this->getOutput(); 00634 $out->addHTML( Xml::element( 'h2', null, $moveLogPage->getName()->text() ) ); 00635 LogEventsList::showLogExtract( $out, 'move', $title ); 00636 } 00637 00638 function showSubpages( $title ) { 00639 if( !MWNamespace::hasSubpages( $title->getNamespace() ) ) 00640 return; 00641 00642 $subpages = $title->getSubpages(); 00643 $count = $subpages instanceof TitleArray ? $subpages->count() : 0; 00644 00645 $out = $this->getOutput(); 00646 $out->wrapWikiMsg( '== $1 ==', array( 'movesubpage', $count ) ); 00647 00648 # No subpages. 00649 if ( $count == 0 ) { 00650 $out->addWikiMsg( 'movenosubpage' ); 00651 return; 00652 } 00653 00654 $out->addWikiMsg( 'movesubpagetext', $this->getLanguage()->formatNum( $count ) ); 00655 $out->addHTML( "<ul>\n" ); 00656 00657 foreach( $subpages as $subpage ) { 00658 $link = Linker::link( $subpage ); 00659 $out->addHTML( "<li>$link</li>\n" ); 00660 } 00661 $out->addHTML( "</ul>\n" ); 00662 } 00663 }