Index: includes/filerepo/LocalFile.php =================================================================== --- includes/filerepo/LocalFile.php (revision 82017) +++ includes/filerepo/LocalFile.php (working copy) @@ -817,6 +817,7 @@ if ( $status->ok ) { if ( !$this->recordUpload2( $status->value, $comment, $pageText, $props, $timestamp, $user ) ) { + $this->unpublish(); $status->fatal( 'filenotfound', $srcPath ); } } @@ -968,11 +969,6 @@ $article = new ImagePage( $descTitle ); $article->setFile( $this ); - # Add the log entry - $log = new LogPage( 'upload' ); - $action = $reupload ? 'overwrite' : 'upload'; - $log->addEntry( $action, $descTitle, $comment, array(), $user ); - if ( $descTitle->exists() ) { # Create a null revision $latest = $descTitle->getLatestRevID(); @@ -994,9 +990,26 @@ # New file; create the description page. # There's already a log entry, so don't make a second RC entry # Squid and file cache for the description page are purged by doEdit. - $article->doEdit( $pageText, $comment, EDIT_NEW | EDIT_SUPPRESS_RC ); + $status = $article->doEdit( $pageText, $comment, EDIT_NEW | EDIT_SUPPRESS_RC ); + + if ( !$reupload ) { + # Storing the article failed, so we are going to rollback and + # show an error to to the user. We can't just rollback using + # $dbw->rollback because of nasty transaction nesting, see + # bug 15430. Since this is a not reupload, we simply do DELETE + # on the image table + $dbw->delete( 'image', array( 'img_name' => $this->getName() ), __METHOD__ ); + $dbw->commit(); + # Caller should cleanup + return false; + } } + # Add the log entry + $log = new LogPage( 'upload' ); + $action = $reupload ? 'overwrite' : 'upload'; + $log->addEntry( $action, $descTitle, $comment, array(), $user ); + # Commit the transaction now, in case something goes wrong later # The most important thing is that files don't get lost, especially archives $dbw->commit(); @@ -1059,6 +1072,21 @@ return $status; } + + /** + * Remove the file associated with this File. This is a pure file system + * operation and does not move it into the archives, see delete() for that. + * + * @return null + */ + function unpublish() { + $this->lock(); + + $dstRel = $this->getRel(); + $this->repo->cleanupBatch( array( array( 'public', $dstRel ) ) ); + + $this->unlock(); + } /** getLinksTo inherited */ /** getExifData inherited */