Stop overwriting $cache in User::getCacheKey()
[lhc/web/wiklou.git] / includes / MovePage.php
index bb76395..1919c0c 100644 (file)
@@ -21,6 +21,7 @@
 
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Revision\SlotRecord;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Handles the backend logic of moving a page from one title
@@ -249,24 +250,8 @@ class MovePage {
                        return $status;
                }
 
-               // 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->oldTitle->getNamespace() == NS_FILE ) {
-                       $file = wfLocalFile( $this->oldTitle );
-                       $file->load( File::READ_LATEST );
-                       if ( $file->exists() ) {
-                               $status = $file->move( $this->newTitle );
-                               if ( !$status->isOK() ) {
-                                       return $status;
-                               }
-                       }
-                       // Clear RepoGroup process cache
-                       RepoGroup::singleton()->clearCache( $this->oldTitle );
-                       RepoGroup::singleton()->clearCache( $this->newTitle ); # clear false negative cache
-               }
-
-               $dbw->startAtomic( __METHOD__ );
+               $dbw->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
 
                Hooks::run( 'TitleMoveStarting', [ $this->oldTitle, $this->newTitle, $user ] );
 
@@ -394,6 +379,16 @@ class MovePage {
                        $store->duplicateAllAssociatedEntries( $this->oldTitle, $this->newTitle );
                }
 
+               // If it is a file then move it last.
+               // This is done after all database changes so that file system errors cancel the transaction.
+               if ( $this->oldTitle->getNamespace() == NS_FILE ) {
+                       $status = $this->moveFile( $this->oldTitle, $this->newTitle );
+                       if ( !$status->isOK() ) {
+                               $dbw->cancelAtomic( __METHOD__ );
+                               return $status;
+                       }
+               }
+
                Hooks::run(
                        'TitleMoveCompleting',
                        [ $this->oldTitle, $this->newTitle,
@@ -427,6 +422,33 @@ class MovePage {
                return Status::newGood();
        }
 
+       /**
+        * Move a file associated with a page to a new location.
+        * Can also be used to revert after a DB failure.
+        *
+        * @access private
+        * @param Title Old location to move the file from.
+        * @param Title New location to move the file to.
+        * @return Status
+        */
+       private function moveFile( $oldTitle, $newTitle ) {
+               $status = Status::newFatal(
+                       'cannotdelete',
+                       $oldTitle->getPrefixedText()
+               );
+
+               $file = wfLocalFile( $oldTitle );
+               $file->load( File::READ_LATEST );
+               if ( $file->exists() ) {
+                       $status = $file->move( $newTitle );
+               }
+
+               // Clear RepoGroup process cache
+               RepoGroup::singleton()->clearCache( $oldTitle );
+               RepoGroup::singleton()->clearCache( $newTitle ); # clear false negative cache
+               return $status;
+       }
+
        /**
         * Move page to a title which is either a redirect to the
         * source page or nonexistent
@@ -472,7 +494,8 @@ class MovePage {
                        );
 
                        if ( !$status->isGood() ) {
-                               throw new MWException( 'Failed to delete page-move revision: ' . $status );
+                               throw new MWException( 'Failed to delete page-move revision: '
+                                       . $status->getWikiText( false, false, 'en' ) );
                        }
 
                        $nt->resetArticleID( false );