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