}
/**
- * Deletes a batch of (zone, rel) pairs. It will try to delete each pair,
- * but ignores any errors doing so.
+ * Deletes a batch of files. Each file can be a (zone, rel) pairs, a
+ * virtual url or a real path. It will try to delete each file, but
+ * ignores any errors that may occur
*
- * @param $pairs array Pair of (zone, rel) pairs to delete
+ * @param $pairs array List of files to delete
*/
- function cleanupBatch( $pairs ) {
- foreach ( $pairs as $pair ) {
- list( $zone, $rel ) = $pair;
- $root = $this->getZonePath( $zone );
- $path = "$root/$rel";
+ function cleanupBatch( $files ) {
+ foreach ( $files as $file ) {
+ if ( is_array( $file ) ) {
+ // This is a pair, extract it
+ list( $zone, $rel ) = $file;
+ $root = $this->getZonePath( $zone );
+ $path = "$root/$rel";
+ } else {
+ if ( self::isVirtualUrl( $file ) ) {
+ // This is a virtual url, resolve it
+ $path = $this->resolveVirtualUrl( $file );
+ } else {
+ // This is a full file name
+ $path = $file;
+ }
+ }
wfSuppressWarnings();
unlink( $path );
$triplets = $this->getMoveTriplets();
$triplets = $this->removeNonexistentFiles( $triplets );
- $statusDb = $this->doDBUpdates();
- wfDebugLog( 'imagemove', "Renamed {$this->file->name} in database: {$statusDb->successCount} successes, {$statusDb->failCount} failures" );
- $statusMove = $repo->storeBatch( $triplets, FSRepo::DELETE_SOURCE );
+
+ // Copy the files into their new location
+ $statusMove = $repo->storeBatch( $triplets );
wfDebugLog( 'imagemove', "Moved files for {$this->file->name}: {$statusMove->successCount} successes, {$statusMove->failCount} failures" );
-
- if ( !$statusMove->isOk() ) {
+ if ( !$statusMove->isGood() ) {
wfDebugLog( 'imagemove', "Error in moving files: " . $statusMove->getWikiText() );
- $this->db->rollback();
+ $this->cleanupTarget( $triplets );
+ $statusMove->ok = false;
+ return $statusMove;
}
+ $this->db->begin();
+ $statusDb = $this->doDBUpdates();
+ wfDebugLog( 'imagemove', "Renamed {$this->file->name} in database: {$statusDb->successCount} successes, {$statusDb->failCount} failures" );
+ if ( !$statusDb->isGood() ) {
+ $this->db->rollback();
+ // Something went wrong with the DB updates, so remove the target files
+ $this->cleanupTarget( $triplets );
+ $statusDb->ok = false;
+ return $statusDb;
+ }
+ $this->db->commit();
+
+ // Everything went ok, remove the source files
+ $this->cleanupSource( $triplets );
+
$status->merge( $statusDb );
$status->merge( $statusMove );
$status->successCount++;
} else {
$status->failCount++;
+ $status->fatal( 'imageinvalidfilename' );
+ return $status;
}
// Update old images
$total = $this->oldCount;
$status->successCount += $affected;
$status->failCount += $total - $affected;
+ if ( $status->failCount ) {
+ $status->error( 'imageinvalidfilename' );
+ }
return $status;
}
return $filteredTriplets;
}
+
+ /**
+ * Cleanup a partially moved array of triplets by deleting the target
+ * files. Called if something went wrong half way.
+ */
+ function cleanupTarget( $triplets ) {
+ // Create dest pairs from the triplets
+ $pairs = array();
+ foreach ( $triplets as $triplet ) {
+ $pairs[] = array( $triplet[1], $triplet[2] );
+ }
+
+ $this->file->repo->cleanupBatch( $pairs );
+ }
+
+ /**
+ * Cleanup a fully moved array of triplets by deleting the source files.
+ * Called at the end of the move process if everything else went ok.
+ */
+ function cleanupSource( $triplets ) {
+ // Create source file names from the triplets
+ $files = array();
+ foreach ( $triplets as $triplet ) {
+ $files[] = $triplet[0];
+ }
+
+ $this->file->repo->cleanupBatch( $files );
+ }
}