MediaWiki  REL1_20
SpecialMovepage.php
Go to the documentation of this file.
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                                 ) . '&#160;' .
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>&#160;</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 }