Index: trunk/phase3/includes/filerepo/LocalFile.php |
— | — | @@ -2043,16 +2043,32 @@ |
2044 | 2044 | $triplets = $this->getMoveTriplets(); |
2045 | 2045 | |
2046 | 2046 | $triplets = $this->removeNonexistentFiles( $triplets ); |
| 2047 | + |
| 2048 | + // Copy the files into their new location |
| 2049 | + $statusMove = $repo->storeBatch( $triplets ); |
| 2050 | + wfDebugLog( 'imagemove', "Moved files for {$this->file->name}: {$statusMove->successCount} successes, {$statusMove->failCount} failures" ); |
| 2051 | + if ( !$statusMove->isGood() ) { |
| 2052 | + wfDebugLog( 'imagemove', "Error in moving files: " . $statusMove->getWikiText() ); |
| 2053 | + $this->cleanupTarget( $triplets ); |
| 2054 | + $statusMove->ok = false; |
| 2055 | + return $statusMove; |
| 2056 | + } |
| 2057 | + |
| 2058 | + $this->db->begin(); |
2047 | 2059 | $statusDb = $this->doDBUpdates(); |
2048 | 2060 | wfDebugLog( 'imagemove', "Renamed {$this->file->name} in database: {$statusDb->successCount} successes, {$statusDb->failCount} failures" ); |
2049 | | - $statusMove = $repo->storeBatch( $triplets, FSRepo::DELETE_SOURCE ); |
2050 | | - wfDebugLog( 'imagemove', "Moved files for {$this->file->name}: {$statusMove->successCount} successes, {$statusMove->failCount} failures" ); |
2051 | | - |
2052 | | - if ( !$statusMove->isOk() ) { |
2053 | | - wfDebugLog( 'imagemove', "Error in moving files: " . $statusMove->getWikiText() ); |
| 2061 | + if ( !$statusDb->isGood() ) { |
2054 | 2062 | $this->db->rollback(); |
| 2063 | + // Something went wrong with the DB updates, so remove the target files |
| 2064 | + $this->cleanupTarget( $triplets ); |
| 2065 | + $statusDb->ok = false; |
| 2066 | + return $statusDb; |
2055 | 2067 | } |
2056 | | - |
| 2068 | + $this->db->commit(); |
| 2069 | + |
| 2070 | + // Everything went ok, remove the source files |
| 2071 | + $this->cleanupSource( $triplets ); |
| 2072 | + |
2057 | 2073 | $status->merge( $statusDb ); |
2058 | 2074 | $status->merge( $statusMove ); |
2059 | 2075 | |
— | — | @@ -2082,6 +2098,8 @@ |
2083 | 2099 | $status->successCount++; |
2084 | 2100 | } else { |
2085 | 2101 | $status->failCount++; |
| 2102 | + $status->fatal( 'imageinvalidfilename' ); |
| 2103 | + return $status; |
2086 | 2104 | } |
2087 | 2105 | |
2088 | 2106 | // Update old images |
— | — | @@ -2099,6 +2117,9 @@ |
2100 | 2118 | $total = $this->oldCount; |
2101 | 2119 | $status->successCount += $affected; |
2102 | 2120 | $status->failCount += $total - $affected; |
| 2121 | + if ( $status->failCount ) { |
| 2122 | + $status->error( 'imageinvalidfilename' ); |
| 2123 | + } |
2103 | 2124 | |
2104 | 2125 | return $status; |
2105 | 2126 | } |
— | — | @@ -2143,4 +2164,32 @@ |
2144 | 2165 | |
2145 | 2166 | return $filteredTriplets; |
2146 | 2167 | } |
| 2168 | + |
| 2169 | + /** |
| 2170 | + * Cleanup a partially moved array of triplets by deleting the target |
| 2171 | + * files. Called if something went wrong half way. |
| 2172 | + */ |
| 2173 | + function cleanupTarget( $triplets ) { |
| 2174 | + // Create dest pairs from the triplets |
| 2175 | + $pairs = array(); |
| 2176 | + foreach ( $triplets as $triplet ) { |
| 2177 | + $pairs[] = array( $triplet[1], $triplet[2] ); |
| 2178 | + } |
| 2179 | + |
| 2180 | + $this->file->repo->cleanupBatch( $pairs ); |
| 2181 | + } |
| 2182 | + |
| 2183 | + /** |
| 2184 | + * Cleanup a fully moved array of triplets by deleting the source files. |
| 2185 | + * Called at the end of the move process if everything else went ok. |
| 2186 | + */ |
| 2187 | + function cleanupSource( $triplets ) { |
| 2188 | + // Create source file names from the triplets |
| 2189 | + $files = array(); |
| 2190 | + foreach ( $triplets as $triplet ) { |
| 2191 | + $files[] = $triplet[0]; |
| 2192 | + } |
| 2193 | + |
| 2194 | + $this->file->repo->cleanupBatch( $files ); |
| 2195 | + } |
2147 | 2196 | } |
Index: trunk/phase3/includes/filerepo/FSRepo.php |
— | — | @@ -262,16 +262,28 @@ |
263 | 263 | } |
264 | 264 | |
265 | 265 | /** |
266 | | - * Deletes a batch of (zone, rel) pairs. It will try to delete each pair, |
267 | | - * but ignores any errors doing so. |
| 266 | + * Deletes a batch of files. Each file can be a (zone, rel) pairs, a |
| 267 | + * virtual url or a real path. It will try to delete each file, but |
| 268 | + * ignores any errors that may occur |
268 | 269 | * |
269 | | - * @param $pairs array Pair of (zone, rel) pairs to delete |
| 270 | + * @param $pairs array List of files to delete |
270 | 271 | */ |
271 | | - function cleanupBatch( $pairs ) { |
272 | | - foreach ( $pairs as $pair ) { |
273 | | - list( $zone, $rel ) = $pair; |
274 | | - $root = $this->getZonePath( $zone ); |
275 | | - $path = "$root/$rel"; |
| 272 | + function cleanupBatch( $files ) { |
| 273 | + foreach ( $files as $file ) { |
| 274 | + if ( is_array( $file ) ) { |
| 275 | + // This is a pair, extract it |
| 276 | + list( $zone, $rel ) = $file; |
| 277 | + $root = $this->getZonePath( $zone ); |
| 278 | + $path = "$root/$rel"; |
| 279 | + } else { |
| 280 | + if ( self::isVirtualUrl( $file ) ) { |
| 281 | + // This is a virtual url, resolve it |
| 282 | + $path = $this->resolveVirtualUrl( $file ); |
| 283 | + } else { |
| 284 | + // This is a full file name |
| 285 | + $path = $file; |
| 286 | + } |
| 287 | + } |
276 | 288 | |
277 | 289 | wfSuppressWarnings(); |
278 | 290 | unlink( $path ); |