MediaWiki
REL1_19
|
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 = wfMsg( 'delete_and_move' ); 00145 $submitVar = 'wpDeleteAndMove'; 00146 $confirm = " 00147 <tr> 00148 <td></td> 00149 <td class='mw-input'>" . 00150 Xml::checkLabel( wfMsg( 'delete_and_move_confirm' ), '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 = wfMsg( 'movepagebtn' ); 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 $out->addHTML( 00250 Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalURL( 'action=submit' ), 'id' => 'movepage' ) ) . 00251 Xml::openElement( 'fieldset' ) . 00252 Xml::element( 'legend', null, wfMsg( 'move-page-legend' ) ) . 00253 Xml::openElement( 'table', array( 'border' => '0', 'id' => 'mw-movepage-table' ) ) . 00254 "<tr> 00255 <td class='mw-label'>" . 00256 wfMsgHtml( 'movearticle' ) . 00257 "</td> 00258 <td class='mw-input'> 00259 <strong>{$oldTitleLink}</strong> 00260 </td> 00261 </tr> 00262 <tr> 00263 <td class='mw-label'>" . 00264 Xml::label( wfMsg( 'newtitle' ), 'wpNewTitleMain' ) . 00265 "</td> 00266 <td class='mw-input'>" . 00267 Html::namespaceSelector( 00268 array( 'selected' => $newTitle->getNamespace() ), 00269 array( 'name' => 'wpNewTitleNs', 'id' => 'wpNewTitleNs' ) 00270 ) . 00271 Xml::input( 'wpNewTitleMain', 60, $wgContLang->recodeForEdit( $newTitle->getText() ), array( 00272 'type' => 'text', 00273 'id' => 'wpNewTitleMain', 00274 'maxlength' => 255, 00275 ) ) . 00276 Html::hidden( 'wpOldTitle', $this->oldTitle->getPrefixedText() ) . 00277 "</td> 00278 </tr> 00279 <tr> 00280 <td class='mw-label'>" . 00281 Xml::label( wfMsg( 'movereason' ), 'wpReason' ) . 00282 "</td> 00283 <td class='mw-input'>" . 00284 Html::element( 'textarea', array( 'name' => 'wpReason', 'id' => 'wpReason', 'cols' => 60, 'rows' => 2, 00285 'maxlength' => 200 ), $this->reason ) . 00286 "</td> 00287 </tr>" 00288 ); 00289 00290 if( $considerTalk ) { 00291 $out->addHTML( " 00292 <tr> 00293 <td></td> 00294 <td class='mw-input'>" . 00295 Xml::checkLabel( wfMsg( 'movetalk' ), 'wpMovetalk', 'wpMovetalk', $this->moveTalk ) . 00296 "</td> 00297 </tr>" 00298 ); 00299 } 00300 00301 if ( $user->isAllowed( 'suppressredirect' ) ) { 00302 $out->addHTML( " 00303 <tr> 00304 <td></td> 00305 <td class='mw-input' >" . 00306 Xml::checkLabel( wfMsg( 'move-leave-redirect' ), 'wpLeaveRedirect', 00307 'wpLeaveRedirect', $this->leaveRedirect ) . 00308 "</td> 00309 </tr>" 00310 ); 00311 } 00312 00313 if ( $hasRedirects ) { 00314 $out->addHTML( " 00315 <tr> 00316 <td></td> 00317 <td class='mw-input' >" . 00318 Xml::checkLabel( wfMsg( 'fix-double-redirects' ), 'wpFixRedirects', 00319 'wpFixRedirects', $this->fixRedirects ) . 00320 "</td> 00321 </tr>" 00322 ); 00323 } 00324 00325 if( $canMoveSubpage ) { 00326 $out->addHTML( " 00327 <tr> 00328 <td></td> 00329 <td class=\"mw-input\">" . 00330 Xml::check( 00331 'wpMovesubpages', 00332 # Don't check the box if we only have talk subpages to 00333 # move and we aren't moving the talk page. 00334 $this->moveSubpages && ($this->oldTitle->hasSubpages() || $this->moveTalk), 00335 array( 'id' => 'wpMovesubpages' ) 00336 ) . ' ' . 00337 Xml::tags( 'label', array( 'for' => 'wpMovesubpages' ), 00338 wfMsgExt( 00339 ( $this->oldTitle->hasSubpages() 00340 ? 'move-subpages' 00341 : 'move-talk-subpages' ), 00342 array( 'parseinline' ), 00343 $this->getLanguage()->formatNum( $wgMaximumMovedPages ), 00344 # $2 to allow use of PLURAL in message. 00345 $wgMaximumMovedPages 00346 ) 00347 ) . 00348 "</td> 00349 </tr>" 00350 ); 00351 } 00352 00353 $watchChecked = $user->isLoggedIn() && ($this->watch || $user->getBoolOption( 'watchmoves' ) 00354 || $this->oldTitle->userIsWatching()); 00355 # Don't allow watching if user is not logged in 00356 if( $user->isLoggedIn() ) { 00357 $out->addHTML( " 00358 <tr> 00359 <td></td> 00360 <td class='mw-input'>" . 00361 Xml::checkLabel( wfMsg( 'move-watch' ), 'wpWatch', 'watch', $watchChecked ) . 00362 "</td> 00363 </tr>"); 00364 } 00365 00366 $out->addHTML( " 00367 {$confirm} 00368 <tr> 00369 <td> </td> 00370 <td class='mw-submit'>" . 00371 Xml::submitButton( $movepagebtn, array( 'name' => $submitVar ) ) . 00372 "</td> 00373 </tr>" . 00374 Xml::closeElement( 'table' ) . 00375 Html::hidden( 'wpEditToken', $user->getEditToken() ) . 00376 Xml::closeElement( 'fieldset' ) . 00377 Xml::closeElement( 'form' ) . 00378 "\n" 00379 ); 00380 00381 $this->showLogFragment( $this->oldTitle ); 00382 $this->showSubpages( $this->oldTitle ); 00383 00384 } 00385 00386 function doSubmit() { 00387 global $wgMaximumMovedPages, $wgFixDoubleRedirects, $wgDeleteRevisionsLimit; 00388 00389 $user = $this->getUser(); 00390 00391 if ( $user->pingLimiter( 'move' ) ) { 00392 throw new ThrottledError; 00393 } 00394 00395 $ot = $this->oldTitle; 00396 $nt = $this->newTitle; 00397 00398 # don't allow moving to pages with # in 00399 if ( !$nt || $nt->getFragment() != '' ) { 00400 $this->showForm( array( array( 'badtitletext' ) ) ); 00401 return; 00402 } 00403 00404 # Show a warning if the target file exists on a shared repo 00405 if ( $nt->getNamespace() == NS_FILE 00406 && !( $this->moveOverShared && $user->isAllowed( 'reupload-shared' ) ) 00407 && !RepoGroup::singleton()->getLocalRepo()->findFile( $nt ) 00408 && wfFindFile( $nt ) ) 00409 { 00410 $this->showForm( array( array( 'file-exists-sharedrepo' ) ) ); 00411 return; 00412 00413 } 00414 00415 # Delete to make way if requested 00416 if ( $this->deleteAndMove ) { 00417 $permErrors = $nt->getUserPermissionsErrors( 'delete', $user ); 00418 if ( count( $permErrors ) ) { 00419 # Only show the first error 00420 $this->showForm( $permErrors ); 00421 return; 00422 } 00423 00424 $reason = wfMessage( 'delete_and_move_reason', $ot )->inContentLanguage()->text(); 00425 00426 // Delete an associated image if there is 00427 if ( $nt->getNamespace() == NS_FILE ) { 00428 $file = wfLocalFile( $nt ); 00429 if ( $file->exists() ) { 00430 $file->delete( $reason, false ); 00431 } 00432 } 00433 00434 $error = ''; // passed by ref 00435 $page = WikiPage::factory( $nt ); 00436 if ( !$page->doDeleteArticle( $reason, false, 0, true, $error, $user ) ) { 00437 $this->showForm( array( array( 'cannotdelete', wfEscapeWikiText( $nt->getPrefixedText() ) ) ) ); 00438 return; 00439 } 00440 } 00441 00442 if ( $user->isAllowed( 'suppressredirect' ) ) { 00443 $createRedirect = $this->leaveRedirect; 00444 } else { 00445 $createRedirect = true; 00446 } 00447 00448 # Do the actual move. 00449 $error = $ot->moveTo( $nt, true, $this->reason, $createRedirect ); 00450 if ( $error !== true ) { 00451 $this->showForm( $error ); 00452 return; 00453 } 00454 00455 if ( $wgFixDoubleRedirects && $this->fixRedirects ) { 00456 DoubleRedirectJob::fixRedirects( 'move', $ot, $nt ); 00457 } 00458 00459 wfRunHooks( 'SpecialMovepageAfterMove', array( &$this, &$ot, &$nt ) ); 00460 00461 $out = $this->getOutput(); 00462 $out->setPagetitle( wfMsg( 'pagemovedsub' ) ); 00463 00464 $oldLink = Linker::link( 00465 $ot, 00466 null, 00467 array(), 00468 array( 'redirect' => 'no' ) 00469 ); 00470 $newLink = Linker::linkKnown( $nt ); 00471 $oldText = $ot->getPrefixedText(); 00472 $newText = $nt->getPrefixedText(); 00473 00474 $msgName = $createRedirect ? 'movepage-moved-redirect' : 'movepage-moved-noredirect'; 00475 $out->addHTML( wfMessage( 'movepage-moved' )->rawParams( $oldLink, 00476 $newLink )->params( $oldText, $newText )->parseAsBlock() ); 00477 $out->addWikiMsg( $msgName ); 00478 00479 # Now we move extra pages we've been asked to move: subpages and talk 00480 # pages. First, if the old page or the new page is a talk page, we 00481 # can't move any talk pages: cancel that. 00482 if( $ot->isTalkPage() || $nt->isTalkPage() ) { 00483 $this->moveTalk = false; 00484 } 00485 00486 if ( count( $ot->getUserPermissionsErrors( 'move-subpages', $user ) ) ) { 00487 $this->moveSubpages = false; 00488 } 00489 00490 # Next make a list of id's. This might be marginally less efficient 00491 # than a more direct method, but this is not a highly performance-cri- 00492 # tical code path and readable code is more important here. 00493 # 00494 # Note: this query works nicely on MySQL 5, but the optimizer in MySQL 00495 # 4 might get confused. If so, consider rewriting as a UNION. 00496 # 00497 # If the target namespace doesn't allow subpages, moving with subpages 00498 # would mean that you couldn't move them back in one operation, which 00499 # is bad. 00500 # @todo FIXME: A specific error message should be given in this case. 00501 00502 // @todo FIXME: Use Title::moveSubpages() here 00503 $dbr = wfGetDB( DB_MASTER ); 00504 if( $this->moveSubpages && ( 00505 MWNamespace::hasSubpages( $nt->getNamespace() ) || ( 00506 $this->moveTalk && 00507 MWNamespace::hasSubpages( $nt->getTalkPage()->getNamespace() ) 00508 ) 00509 ) ) { 00510 $conds = array( 00511 'page_title' . $dbr->buildLike( $ot->getDBkey() . '/', $dbr->anyString() ) 00512 .' OR page_title = ' . $dbr->addQuotes( $ot->getDBkey() ) 00513 ); 00514 $conds['page_namespace'] = array(); 00515 if( MWNamespace::hasSubpages( $nt->getNamespace() ) ) { 00516 $conds['page_namespace'] []= $ot->getNamespace(); 00517 } 00518 if( $this->moveTalk && MWNamespace::hasSubpages( $nt->getTalkPage()->getNamespace() ) ) { 00519 $conds['page_namespace'] []= $ot->getTalkPage()->getNamespace(); 00520 } 00521 } elseif( $this->moveTalk ) { 00522 $conds = array( 00523 'page_namespace' => $ot->getTalkPage()->getNamespace(), 00524 'page_title' => $ot->getDBkey() 00525 ); 00526 } else { 00527 # Skip the query 00528 $conds = null; 00529 } 00530 00531 $extraPages = array(); 00532 if( !is_null( $conds ) ) { 00533 $extraPages = TitleArray::newFromResult( 00534 $dbr->select( 'page', 00535 array( 'page_id', 'page_namespace', 'page_title' ), 00536 $conds, 00537 __METHOD__ 00538 ) 00539 ); 00540 } 00541 00542 $extraOutput = array(); 00543 $count = 1; 00544 foreach( $extraPages as $oldSubpage ) { 00545 if( $ot->equals( $oldSubpage ) ) { 00546 # Already did this one. 00547 continue; 00548 } 00549 00550 $newPageName = preg_replace( 00551 '#^'.preg_quote( $ot->getDBkey(), '#' ).'#', 00552 StringUtils::escapeRegexReplacement( $nt->getDBkey() ), # bug 21234 00553 $oldSubpage->getDBkey() 00554 ); 00555 if( $oldSubpage->isTalkPage() ) { 00556 $newNs = $nt->getTalkPage()->getNamespace(); 00557 } else { 00558 $newNs = $nt->getSubjectPage()->getNamespace(); 00559 } 00560 # Bug 14385: we need makeTitleSafe because the new page names may 00561 # be longer than 255 characters. 00562 $newSubpage = Title::makeTitleSafe( $newNs, $newPageName ); 00563 if( !$newSubpage ) { 00564 $oldLink = Linker::linkKnown( $oldSubpage ); 00565 $extraOutput []= wfMsgHtml( 'movepage-page-unmoved', $oldLink, 00566 htmlspecialchars(Title::makeName( $newNs, $newPageName ))); 00567 continue; 00568 } 00569 00570 # This was copy-pasted from Renameuser, bleh. 00571 if ( $newSubpage->exists() && !$oldSubpage->isValidMoveTarget( $newSubpage ) ) { 00572 $link = Linker::linkKnown( $newSubpage ); 00573 $extraOutput []= wfMsgHtml( 'movepage-page-exists', $link ); 00574 } else { 00575 $success = $oldSubpage->moveTo( $newSubpage, true, $this->reason, $createRedirect ); 00576 if( $success === true ) { 00577 if ( $this->fixRedirects ) { 00578 DoubleRedirectJob::fixRedirects( 'move', $oldSubpage, $newSubpage ); 00579 } 00580 $oldLink = Linker::link( 00581 $oldSubpage, 00582 null, 00583 array(), 00584 array( 'redirect' => 'no' ) 00585 ); 00586 $newLink = Linker::linkKnown( $newSubpage ); 00587 $extraOutput []= wfMsgHtml( 'movepage-page-moved', $oldLink, $newLink ); 00588 ++$count; 00589 if( $count >= $wgMaximumMovedPages ) { 00590 $extraOutput []= wfMsgExt( 'movepage-max-pages', array( 'parsemag', 'escape' ), $this->getLanguage()->formatNum( $wgMaximumMovedPages ) ); 00591 break; 00592 } 00593 } else { 00594 $oldLink = Linker::linkKnown( $oldSubpage ); 00595 $newLink = Linker::link( $newSubpage ); 00596 $extraOutput []= wfMsgHtml( 'movepage-page-unmoved', $oldLink, $newLink ); 00597 } 00598 } 00599 00600 } 00601 00602 if( $extraOutput !== array() ) { 00603 $out->addHTML( "<ul>\n<li>" . implode( "</li>\n<li>", $extraOutput ) . "</li>\n</ul>" ); 00604 } 00605 00606 # Deal with watches (we don't watch subpages) 00607 if( $this->watch && $user->isLoggedIn() ) { 00608 $user->addWatch( $ot ); 00609 $user->addWatch( $nt ); 00610 } else { 00611 $user->removeWatch( $ot ); 00612 $user->removeWatch( $nt ); 00613 } 00614 00615 # Re-clear the file redirect cache, which may have been polluted by 00616 # parsing in messages above. See CR r56745. 00617 # @todo FIXME: Needs a more robust solution inside FileRepo. 00618 if( $ot->getNamespace() == NS_FILE ) { 00619 RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect( $ot ); 00620 } 00621 } 00622 00623 function showLogFragment( $title ) { 00624 $out = $this->getOutput(); 00625 $out->addHTML( Xml::element( 'h2', null, LogPage::logName( 'move' ) ) ); 00626 LogEventsList::showLogExtract( $out, 'move', $title ); 00627 } 00628 00629 function showSubpages( $title ) { 00630 if( !MWNamespace::hasSubpages( $title->getNamespace() ) ) 00631 return; 00632 00633 $subpages = $title->getSubpages(); 00634 $count = $subpages instanceof TitleArray ? $subpages->count() : 0; 00635 00636 $out = $this->getOutput(); 00637 $out->wrapWikiMsg( '== $1 ==', array( 'movesubpage', $count ) ); 00638 00639 # No subpages. 00640 if ( $count == 0 ) { 00641 $out->addWikiMsg( 'movenosubpage' ); 00642 return; 00643 } 00644 00645 $out->addWikiMsg( 'movesubpagetext', $this->getLanguage()->formatNum( $count ) ); 00646 $out->addHTML( "<ul>\n" ); 00647 00648 foreach( $subpages as $subpage ) { 00649 $link = Linker::link( $subpage ); 00650 $out->addHTML( "<li>$link</li>\n" ); 00651 } 00652 $out->addHTML( "</ul>\n" ); 00653 } 00654 }