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