[FileRepo]
authorAaron Schulz <aaron@users.mediawiki.org>
Wed, 14 Mar 2012 21:30:26 +0000 (21:30 +0000)
committerAaron Schulz <aaron@users.mediawiki.org>
Wed, 14 Mar 2012 21:30:26 +0000 (21:30 +0000)
* Added getReadOnlyReason() function to FileRepo to check read-only status. Added such checks to the File object functions that mutate files in storage. This should make read-only mode more tolerable (which is needed at least briefly when switching backends).
* Added lock()/unlock() calls to File restore() function.
* Use proper isOK() accessor for Status objects.

includes/filerepo/FileRepo.php
includes/filerepo/file/LocalFile.php
languages/messages/MessagesEn.php
maintenance/language/messages.inc

index 0dd5466..1475043 100644 (file)
@@ -119,6 +119,15 @@ class FileRepo {
                return $this->backend;
        }
 
+       /**
+        * Get an explanatory message if this repo is read-only
+        * 
+        * @return string|bool Returns false if the repo is not read-only
+        */
+       public function getReadOnlyReason() {
+               return $this->backend->getReadOnlyReason();
+       }
+
        /**
         * Prepare a single zone or list of zones for usage.
         * See initDeletedDir() for additional setup needed for the 'deleted' zone.
index ea8d7a3..27c412f 100644 (file)
@@ -908,9 +908,13 @@ class LocalFile extends File {
         */
        function upload( $srcPath, $comment, $pageText, $flags = 0, $props = false, $timestamp = false, $user = null ) {
                global $wgContLang;
+
+               if ( $this->getRepo()->getReadOnlyReason() !== false ) {
+                       return $this->readOnlyFatalStatus();
+               }
+
                // truncate nicely or the DB will do it for us
-               // non-nicely (dangling multi-byte chars, non-truncated
-               // version in cache).
+               // non-nicely (dangling multi-byte chars, non-truncated version in cache).
                $comment = $wgContLang->truncate( $comment, 255 );
                $this->lock(); // begin
                $status = $this->publish( $srcPath, $flags );
@@ -1175,6 +1179,10 @@ class LocalFile extends File {
         *     archive name, or an empty string if it was a new file.
         */
        function publishTo( $srcPath, $dstRel, $flags = 0 ) {
+               if ( $this->getRepo()->getReadOnlyReason() !== false ) {
+                       return $this->readOnlyFatalStatus();
+               }
+
                $this->lock(); // begin
 
                $archiveName = wfTimestamp( TS_MW ) . '!'. $this->getName();
@@ -1211,6 +1219,10 @@ class LocalFile extends File {
         * @return FileRepoStatus object.
         */
        function move( $target ) {
+               if ( $this->getRepo()->getReadOnlyReason() !== false ) {
+                       return $this->readOnlyFatalStatus();
+               }
+
                wfDebugLog( 'imagemove', "Got request to move {$this->name} to " . $target->getText() );
                $this->lock(); // begin
 
@@ -1250,6 +1262,10 @@ class LocalFile extends File {
         * @return FileRepoStatus object.
         */
        function delete( $reason, $suppress = false ) {
+               if ( $this->getRepo()->getReadOnlyReason() !== false ) {
+                       return $this->readOnlyFatalStatus();
+               }
+
                $this->lock(); // begin
 
                $batch = new LocalFileDeleteBatch( $this, $reason, $suppress );
@@ -1266,7 +1282,7 @@ class LocalFile extends File {
                }
                $status = $batch->execute();
 
-               if ( $status->ok ) {
+               if ( $status->isOK() ) {
                        // Update site_stats
                        $site_stats = $dbw->tableName( 'site_stats' );
                        $dbw->query( "UPDATE $site_stats SET ss_images=ss_images-1", __METHOD__ );
@@ -1293,6 +1309,10 @@ class LocalFile extends File {
         * @return FileRepoStatus object.
         */
        function deleteOld( $archiveName, $reason, $suppress = false ) {
+               if ( $this->getRepo()->getReadOnlyReason() !== false ) {
+                       return $this->readOnlyFatalStatus();
+               }
+
                $this->lock(); // begin
 
                $batch = new LocalFileDeleteBatch( $this, $reason, $suppress );
@@ -1302,7 +1322,7 @@ class LocalFile extends File {
 
                $this->unlock(); // done
 
-               if ( $status->ok ) {
+               if ( $status->isOK() ) {
                        $this->purgeDescription();
                        $this->purgeHistory();
                }
@@ -1322,6 +1342,12 @@ class LocalFile extends File {
         * @return FileRepoStatus
         */
        function restore( $versions = array(), $unsuppress = false ) {
+               if ( $this->getRepo()->getReadOnlyReason() !== false ) {
+                       return $this->readOnlyFatalStatus();
+               }
+
+               $this->lock(); // begin
+
                $batch = new LocalFileRestoreBatch( $this, $unsuppress );
 
                if ( !$versions ) {
@@ -1332,14 +1358,14 @@ class LocalFile extends File {
 
                $status = $batch->execute();
 
-               if ( !$status->isGood() ) {
-                       return $status;
+               if ( $status->isGood() ) {
+                       $cleanupStatus = $batch->cleanup();
+                       $cleanupStatus->successCount = 0;
+                       $cleanupStatus->failCount = 0;
+                       $status->merge( $cleanupStatus );
                }
 
-               $cleanupStatus = $batch->cleanup();
-               $cleanupStatus->successCount = 0;
-               $cleanupStatus->failCount = 0;
-               $status->merge( $cleanupStatus );
+               $this->unlock(); // done
 
                return $status;
        }
@@ -1443,6 +1469,14 @@ class LocalFile extends File {
                $dbw = $this->repo->getMasterDB();
                $dbw->rollback( __METHOD__ );
        }
+
+       /**
+        * @return Status 
+        */
+       protected function readOnlyFatalStatus() {
+               return $this->getRepo()->newFatal( 'filereadonlyerror', $this->getName(),
+                       $this->getRepo()->getName(), $this->getRepo()->getReadOnlyReason() );
+       }
 } // LocalFile class
 
 # ------------------------------------------------------------------------------
@@ -1710,7 +1744,7 @@ class LocalFileDeleteBatch {
                        $this->status->merge( $status );
                }
 
-               if ( !$this->status->ok ) {
+               if ( !$this->status->isOK() ) {
                        // Critical file deletion error
                        // Roll back inserts, release lock and abort
                        // TODO: delete the defunct filearchive rows if we are using a non-transactional DB
index fc876e2..9af73a7 100644 (file)
@@ -997,6 +997,9 @@ Please report this to an [[Special:ListUsers/sysop|administrator]], making note
 'directorycreateerror' => 'Could not create directory "$1".',
 'filenotfound'         => 'Could not find file "$1".',
 'fileexistserror'      => 'Unable to write to file "$1": File exists.',
+'filereadonlyerror'    => 'Unable to the modify the file "$1" because the file repository "$2" is in read-only mode.
+       
+The administrator who locked it offered this explanation: "$3".',
 'unexpected'           => 'Unexpected value: "$1"="$2".',
 'formerror'            => 'Error: Could not submit form.',
 'badarticleerror'      => 'This action cannot be performed on this page.',
index 6e6e8d0..093305e 100644 (file)
@@ -408,6 +408,7 @@ $wgMessageStructure = array(
                'customjsprotected',
                'ns-specialprotected',
                'titleprotected',
+               'filereadonlyerror'
        ),
        'virus' => array(
                'virus-badscanner',