- // If it is a file, move it first.
- // It is done before all other moving stuff is done because it's hard to revert.
- $dbw = wfGetDB( DB_MASTER );
- if ( $this->getNamespace() == NS_FILE ) {
- $file = wfLocalFile( $this );
- if ( $file->exists() ) {
- $status = $file->move( $nt );
- if ( !$status->isOk() ) {
- return $status->getErrorsArray();
- }
- }
- // Clear RepoGroup process cache
- RepoGroup::singleton()->clearCache( $this );
- RepoGroup::singleton()->clearCache( $nt ); # clear false negative cache
- }
-
- $dbw->begin( __METHOD__ ); # If $file was a LocalFile, its transaction would have closed our own.
- $pageid = $this->getArticleID( self::GAID_FOR_UPDATE );
- $protected = $this->isProtected();
-
- // Do the actual move
- $this->moveToInternal( $nt, $reason, $createRedirect );
-
- // Refresh the sortkey for this row. Be careful to avoid resetting
- // cl_timestamp, which may disturb time-based lists on some sites.
- // @todo This block should be killed, it's duplicating code
- // from LinksUpdate::getCategoryInsertions() and friends.
- $prefixes = $dbw->select(
- 'categorylinks',
- array( 'cl_sortkey_prefix', 'cl_to' ),
- array( 'cl_from' => $pageid ),
- __METHOD__
- );
- if ( $nt->getNamespace() == NS_CATEGORY ) {
- $type = 'subcat';
- } elseif ( $nt->getNamespace() == NS_FILE ) {
- $type = 'file';
- } else {
- $type = 'page';
- }
- foreach ( $prefixes as $prefixRow ) {
- $prefix = $prefixRow->cl_sortkey_prefix;
- $catTo = $prefixRow->cl_to;
- $dbw->update( 'categorylinks',
- array(
- 'cl_sortkey' => Collation::singleton()->getSortKey(
- $nt->getCategorySortkey( $prefix ) ),
- 'cl_collation' => $wgCategoryCollation,
- 'cl_type' => $type,
- 'cl_timestamp=cl_timestamp' ),
- array(
- 'cl_from' => $pageid,
- 'cl_to' => $catTo ),
- __METHOD__
- );
- }
-
- $redirid = $this->getArticleID();
-
- if ( $protected ) {
- # Protect the redirect title as the title used to be...
- $dbw->insertSelect( 'page_restrictions', 'page_restrictions',
- array(
- 'pr_page' => $redirid,
- 'pr_type' => 'pr_type',
- 'pr_level' => 'pr_level',
- 'pr_cascade' => 'pr_cascade',
- 'pr_user' => 'pr_user',
- 'pr_expiry' => 'pr_expiry'
- ),
- array( 'pr_page' => $pageid ),
- __METHOD__,
- array( 'IGNORE' )
- );
- # Update the protection log
- $log = new LogPage( 'protect' );
- $comment = wfMessage(
- 'prot_1movedto2',
- $this->getPrefixedText(),
- $nt->getPrefixedText()
- )->inContentLanguage()->text();
- if ( $reason ) {
- $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
- }
- // @todo FIXME: $params?
- $logId = $log->addEntry(
- 'move_prot',
- $nt,
- $comment,
- array( $this->getPrefixedText() ),
- $wgUser
- );
-
- // reread inserted pr_ids for log relation
- $insertedPrIds = $dbw->select(
- 'page_restrictions',
- 'pr_id',
- array( 'pr_page' => $redirid ),
- __METHOD__
- );
- $logRelationsValues = array();
- foreach ( $insertedPrIds as $prid ) {
- $logRelationsValues[] = $prid->pr_id;
- }
- $log->addRelations( 'pr_id', $logRelationsValues, $logId );
- }
-
- // Update *_from_namespace fields as needed
- if ( $this->getNamespace() != $nt->getNamespace() ) {
- $dbw->update( 'pagelinks',
- array( 'pl_from_namespace' => $nt->getNamespace() ),
- array( 'pl_from' => $pageid ),
- __METHOD__
- );
- $dbw->update( 'templatelinks',
- array( 'tl_from_namespace' => $nt->getNamespace() ),
- array( 'tl_from' => $pageid ),
- __METHOD__
- );
- $dbw->update( 'imagelinks',
- array( 'il_from_namespace' => $nt->getNamespace() ),
- array( 'il_from' => $pageid ),
- __METHOD__
- );
- }
-
- # Update watchlists
- $oldtitle = $this->getDBkey();
- $newtitle = $nt->getDBkey();
- $oldsnamespace = MWNamespace::getSubject( $this->getNamespace() );
- $newsnamespace = MWNamespace::getSubject( $nt->getNamespace() );
- if ( $oldsnamespace != $newsnamespace || $oldtitle != $newtitle ) {
- WatchedItem::duplicateEntries( $this, $nt );
- }
-
- $dbw->commit( __METHOD__ );
-
- wfRunHooks( 'TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid, $reason ) );
- return true;
- }
-
- /**
- * Move page to a title which is either a redirect to the
- * source page or nonexistent
- *
- * @param Title $nt The page to move to, which should be a redirect or nonexistent
- * @param string $reason The reason for the move
- * @param bool $createRedirect Whether to leave a redirect at the old title. Does not check
- * if the user has the suppressredirect right
- * @throws MWException
- */
- private function moveToInternal( &$nt, $reason = '', $createRedirect = true ) {
- global $wgUser, $wgContLang;
-
- if ( $nt->exists() ) {
- $moveOverRedirect = true;
- $logType = 'move_redir';
- } else {
- $moveOverRedirect = false;
- $logType = 'move';
- }
-
- if ( $createRedirect ) {
- if ( $this->getNamespace() == NS_CATEGORY
- && !wfMessage( 'category-move-redirect-override' )->inContentLanguage()->isDisabled()
- ) {
- $redirectContent = new WikitextContent(
- wfMessage( 'category-move-redirect-override' )
- ->params( $nt->getPrefixedText() )->inContentLanguage()->plain() );
- } else {
- $contentHandler = ContentHandler::getForTitle( $this );
- $redirectContent = $contentHandler->makeRedirectContent( $nt,
- wfMessage( 'move-redirect-text' )->inContentLanguage()->plain() );
- }
-
- // NOTE: If this page's content model does not support redirects, $redirectContent will be null.