$dbw->update( 'image',
array(
+ 'img_size' => $this->size, // sanity
'img_width' => $this->width,
'img_height' => $this->height,
'img_bits' => $this->bits,
/**
* Fix thumbnail files from 1.4 or before, with extreme prejudice
+ * @TODO: do we still care about this? Perhaps a maintenance script
+ * can be made instead. Enabling this code results in a serious
+ * RTT regression for wikis without 404 handling.
*/
function migrateThumbFile( $thumbName ) {
$thumbDir = $this->getThumbPath();
}
*/
+ /*
if ( $this->repo->fileExists( $thumbDir ) ) {
// Delete file where directory should be
$this->repo->cleanupBatch( array( $thumbDir ) );
}
+ */
}
/** getHandler inherited */
* @return array first element is the base dir, then files in that base dir.
*/
function getThumbnails( $archiveName = false ) {
- $this->load();
-
if ( $archiveName ) {
$dir = $this->getArchiveThumbPath( $archiveName );
} else {
*/
function purgeOldThumbnails( $archiveName ) {
global $wgUseSquid;
+ wfProfileIn( __METHOD__ );
+
// Get a list of old thumbnails and URLs
$files = $this->getThumbnails( $archiveName );
$dir = array_shift( $files );
}
SquidUpdate::purge( $urls );
}
+
+ wfProfileOut( __METHOD__ );
}
/**
*/
function purgeThumbnails( $options = array() ) {
global $wgUseSquid;
+ wfProfileIn( __METHOD__ );
// Delete thumbnails
$files = $this->getThumbnails();
}
SquidUpdate::purge( $urls );
}
+
+ wfProfileOut( __METHOD__ );
}
/**
function recordUpload2(
$oldver, $comment, $pageText, $props = false, $timestamp = false, $user = null
) {
+ wfProfileIn( __METHOD__ );
+
if ( is_null( $user ) ) {
global $wgUser;
$user = $wgUser;
$dbw->begin( __METHOD__ );
if ( !$props ) {
+ wfProfileIn( __METHOD__ . '-getProps' );
$props = $this->repo->getFileProps( $this->getVirtualUrl() );
+ wfProfileOut( __METHOD__ . -'getProps' );
}
if ( $timestamp === false ) {
$props['timestamp'] = wfTimestamp( TS_MW, $timestamp ); // DB -> TS_MW
$this->setProps( $props );
- # Delete thumbnails
- $this->purgeThumbnails();
-
- # The file is already on its final location, remove it from the squid cache
- SquidUpdate::purge( array( $this->getURL() ) );
-
# Fail now if the file isn't there
if ( !$this->fileExists ) {
wfDebug( __METHOD__ . ": File " . $this->getRel() . " went missing!\n" );
+ wfProfileOut( __METHOD__ );
return false;
}
__METHOD__,
'IGNORE'
);
-
if ( $dbw->affectedRows() == 0 ) {
# (bug 34993) Note: $oldver can be empty here, if the previous
# version of the file was broken. Allow registration of the new
$action = $reupload ? 'overwrite' : 'upload';
$log->addEntry( $action, $descTitle, $comment, array(), $user );
+ wfProfileIn( __METHOD__ . '-edit' );
if ( $descTitle->exists() ) {
# Create a null revision
$latest = $descTitle->getLatestRevID();
# Squid and file cache for the description page are purged by doEdit.
$wikiPage->doEdit( $pageText, $comment, EDIT_NEW | EDIT_SUPPRESS_RC, false, $user );
}
+ wfProfileOut( __METHOD__ . '-edit' );
# Commit the transaction now, in case something goes wrong later
# The most important thing is that files don't get lost, especially archives
# which in fact doesn't really exist (bug 24978)
$this->saveToCache();
+ if ( $reupload ) {
+ # Delete old thumbnails
+ wfProfileIn( __METHOD__ . '-purge' );
+ $this->purgeThumbnails();
+ wfProfileOut( __METHOD__ . '-purge' );
+
+ # Remove the old file from the squid cache
+ SquidUpdate::purge( array( $this->getURL() ) );
+ }
+
# Hooks, hooks, the magic of hooks...
+ wfProfileIn( __METHOD__ . '-hooks' );
wfRunHooks( 'FileUpload', array( $this, $reupload, $descTitle->exists() ) );
+ wfProfileOut( __METHOD__ . '-hooks' );
# Invalidate cache for all pages using this file
$update = new HTMLCacheUpdate( $this->getTitle(), 'imagelinks' );
$update->doUpdate();
}
+ wfProfileOut( __METHOD__ );
return true;
}
*/
function getDescriptionText() {
global $wgParser;
- $revision = Revision::newFromTitle( $this->title );
+ $revision = Revision::newFromTitle( $this->title, false, Revision::AVOID_MASTER );
if ( !$revision ) return false;
$text = $revision->getText();
if ( !$text ) return false;
/**
* @return string
*/
- function getDescription() {
+ function getDescription( $audience = self::FOR_PUBLIC, User $user = null ) {
$this->load();
- return $this->description;
+ if ( $audience == self::FOR_PUBLIC && $this->isDeleted( self::DELETED_COMMENT ) ) {
+ return '';
+ } elseif ( $audience == self::FOR_THIS_USER
+ && !$this->userCan( self::DELETED_COMMENT, $user ) )
+ {
+ return '';
+ } else {
+ return $this->description;
+ }
}
/**
* @return FileRepoStatus
*/
function execute() {
- global $wgUseSquid;
wfProfileIn( __METHOD__ );
$this->file->lock();
$triplets = $this->getMoveTriplets();
$triplets = $this->removeNonexistentFiles( $triplets );
- // Copy the files into their new location
- $statusMove = $repo->storeBatch( $triplets );
- wfDebugLog( 'imagemove', "Moved files for {$this->file->getName()}: {$statusMove->successCount} successes, {$statusMove->failCount} failures" );
- if ( !$statusMove->isGood() ) {
- wfDebugLog( 'imagemove', "Error in moving files: " . $statusMove->getWikiText() );
- $this->cleanupTarget( $triplets );
- $statusMove->ok = false;
- return $statusMove;
- }
-
$this->file->lock(); // begin
+ // Rename the file versions metadata in the DB.
+ // This implicitly locks the destination file, which avoids race conditions.
+ // If we moved the files from A -> C before DB updates, another process could
+ // move files from B -> C at this point, causing storeBatch() to fail and thus
+ // cleanupTarget() to trigger. It would delete the C files and cause data loss.
$statusDb = $this->doDBUpdates();
- wfDebugLog( 'imagemove', "Renamed {$this->file->getName()} in database: {$statusDb->successCount} successes, {$statusDb->failCount} failures" );
if ( !$statusDb->isGood() ) {
$this->file->unlockAndRollback();
- // Something went wrong with the DB updates, so remove the target files
- $this->cleanupTarget( $triplets );
$statusDb->ok = false;
return $statusDb;
}
+ wfDebugLog( 'imagemove', "Renamed {$this->file->getName()} in database: {$statusDb->successCount} successes, {$statusDb->failCount} failures" );
+
+ // Copy the files into their new location.
+ // If a prior process fataled copying or cleaning up files we tolerate any
+ // of the existing files if they are identical to the ones being stored.
+ $statusMove = $repo->storeBatch( $triplets, FileRepo::OVERWRITE_SAME );
+ wfDebugLog( 'imagemove', "Moved files for {$this->file->getName()}: {$statusMove->successCount} successes, {$statusMove->failCount} failures" );
+ if ( !$statusMove->isGood() ) {
+ // Delete any files copied over (while the destination is still locked)
+ $this->cleanupTarget( $triplets );
+ $this->file->unlockAndRollback(); // unlocks the destination
+ wfDebugLog( 'imagemove', "Error in moving files: " . $statusMove->getWikiText() );
+ $statusMove->ok = false;
+ return $statusMove;
+ }
$this->file->unlock(); // done
// Everything went ok, remove the source files
// Create dest pairs from the triplets
$pairs = array();
foreach ( $triplets as $triplet ) {
+ // $triplet: (old source virtual URL, dst zone, dest rel)
$pairs[] = array( $triplet[1], $triplet[2] );
}