r49896 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r49895‎ | r49896 | r49897 >
Date:11:12, 26 April 2009
Author:vasilievvv
Status:ok
Tags:
Comment:
* (bug 18420) Missing file revisions are handled gracefully now:
** Missing files are rendered correctly now (no thumbnail, no link to them)
** Missing files may be now moved, deleted and undeleted
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/includes/ImagePage.php (modified) (history)
  • /trunk/phase3/includes/filerepo/File.php (modified) (history)
  • /trunk/phase3/includes/filerepo/LocalFile.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/ImagePage.php
@@ -438,12 +438,15 @@
439439
440440 if($showLink) {
441441 $filename = wfEscapeWikiText( $this->displayImg->getName() );
 442+ $medialink = $this->displayImg->isMissing() ?
 443+ "'''$filename'''" :
 444+ "[[Media:$filename|$filename]]";
442445
443446 if( !$this->displayImg->isSafeFile() ) {
444447 $warning = wfMsgNoTrans( 'mediawarning' );
445448 $wgOut->addWikiText( <<<EOT
446449 <div class="fullMedia">
447 -<span class="dangerousLink">[[Media:$filename|$filename]]</span>$dirmark
 450+<span class="dangerousLink">{$medialink}</span>$dirmark
448451 <span class="fileInfo">$longDesc</span>
449452 </div>
450453 <div class="mediaWarning">$warning</div>
@@ -452,7 +455,7 @@
453456 } else {
454457 $wgOut->addWikiText( <<<EOT
455458 <div class="fullMedia">
456 -[[Media:$filename|$filename]]$dirmark
 459+{$medialink}{$dirmark}
457460 <span class="fileInfo">$longDesc</span>
458461 </div>
459462 EOT
@@ -852,19 +855,24 @@
853856 if( !$file->userCan(File::DELETED_FILE) ) {
854857 # Don't link to unviewable files
855858 $row .= '<span class="history-deleted">' . $wgLang->timeAndDate( $timestamp, true ) . '</span>';
856 - } else if( $file->isDeleted(File::DELETED_FILE) ) {
 859+ } elseif( $file->isDeleted(File::DELETED_FILE) ) {
857860 $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
858861 # Make a link to review the image
859862 $url = $this->skin->makeKnownLinkObj( $revdel, $wgLang->timeAndDate( $timestamp, true ),
860863 "target=".$wgTitle->getPrefixedText()."&file=$sha1.".$this->current->getExtension() );
861864 $row .= '<span class="history-deleted">'.$url.'</span>';
 865+ } elseif( $file->isMissing() ) {
 866+ # Don't link to missing files
 867+ $row .= $wgLang->timeAndDate( $timestamp, true );
862868 } else {
863869 $url = $iscur ? $this->current->getUrl() : $this->current->getArchiveUrl( $img );
864870 $row .= Xml::element( 'a', array( 'href' => $url ), $wgLang->timeAndDate( $timestamp, true ) );
865871 }
866872
867873 // Thumbnail
868 - if( $file->allowInlineDisplay() && $file->userCan( File::DELETED_FILE ) && !$file->isDeleted( File::DELETED_FILE ) ) {
 874+ if( $file->isMissing() ) {
 875+ $row .= '</td><td><strong class="error">' . wfMsgHtml( 'filehist-missing' ) . '</strong>';
 876+ } elseif( $file->allowInlineDisplay() && $file->userCan( File::DELETED_FILE ) && !$file->isDeleted( File::DELETED_FILE ) ) {
869877 $params = array(
870878 'width' => '120',
871879 'height' => '120',
Index: trunk/phase3/includes/filerepo/LocalFile.php
@@ -49,6 +49,7 @@
5050 $dataLoaded, # Whether or not all this has been loaded from the database (loadFromXxx)
5151 $upgraded, # Whether the row was upgraded on load
5252 $locked, # True if the image row is locked
 53+ $missing, # True if file is not present in file system. Not to be cached in memcached
5354 $deleted; # Bitfield akin to rev_deleted
5455
5556 /**#@-*/
@@ -394,6 +395,14 @@
395396 /** getPath inherited */
396397 /** isVisible inhereted */
397398
 399+ function isMissing() {
 400+ if( $this->missing === null ) {
 401+ list( $fileExists ) = $this->repo->fileExistsBatch( array( $this->getVirtualUrl() ), FileRepo::FILES_ONLY );
 402+ $this->missing = !$fileExists;
 403+ }
 404+ return $this->missing;
 405+ }
 406+
398407 /**
399408 * Return the width of the image
400409 *
@@ -1432,6 +1441,9 @@
14331442 // them in a separate transaction, then run the file ops, then update the fa_name fields.
14341443 $this->doDBInserts();
14351444
 1445+ // Removes non-existent file from the batch, so we don't get errors.
 1446+ $this->deletionBatch = $this->removeNonexistentFiles( $this->deletionBatch );
 1447+
14361448 // Execute the file deletion batch
14371449 $status = $this->file->repo->deleteBatch( $this->deletionBatch );
14381450 if ( !$status->isGood() ) {
@@ -1465,6 +1477,22 @@
14661478 wfProfileOut( __METHOD__ );
14671479 return $this->status;
14681480 }
 1481+
 1482+ /**
 1483+ * Removes non-existent files from a deletion batch.
 1484+ */
 1485+ function removeNonexistentFiles( $batch ) {
 1486+ $files = $newBatch = array();
 1487+ foreach( $batch as $batchItem ) {
 1488+ list( $src, $dest ) = $batchItem;
 1489+ $files[$src] = $this->file->repo->getVirtualUrl( 'public' ) . '/' . rawurlencode( $src );
 1490+ }
 1491+ $result = $this->file->repo->fileExistsBatch( $files, FSRepo::FILES_ONLY );
 1492+ foreach( $batch as $batchItem )
 1493+ if( $result[$batchItem[0]] )
 1494+ $newBatch[] = $batchItem;
 1495+ return $newBatch;
 1496+ }
14691497 }
14701498
14711499 #------------------------------------------------------------------------------
@@ -1657,6 +1685,9 @@
16581686 $status->error( 'undelete-missing-filearchive', $id );
16591687 }
16601688
 1689+ // Remove missing files from batch, so we don't get errors when undeleting them
 1690+ $storeBatch = $this->removeNonexistentFiles( $storeBatch );
 1691+
16611692 // Run the store batch
16621693 // Use the OVERWRITE_SAME flag to smooth over a common error
16631694 $storeStatus = $this->file->repo->storeBatch( $storeBatch, FileRepo::OVERWRITE_SAME );
@@ -1687,7 +1718,7 @@
16881719 __METHOD__ );
16891720 }
16901721
1691 - if( $status->successCount > 0 ) {
 1722+ if( $status->successCount > 0 || !$storeBatch ) { // If store batch is empty (all files are missing), deletion is to be considered successful
16921723 if( !$exists ) {
16931724 wfDebug( __METHOD__." restored {$status->successCount} items, creating a new current\n" );
16941725
@@ -1707,6 +1738,38 @@
17081739 }
17091740
17101741 /**
 1742+ * Removes non-existent files from a store batch.
 1743+ */
 1744+ function removeNonexistentFiles( $triplets ) {
 1745+ $files = $filteredTriplets = array();
 1746+ foreach( $triplets as $file )
 1747+ $files[$file[0]] = $file[0];
 1748+ $result = $this->file->repo->fileExistsBatch( $files, FSRepo::FILES_ONLY );
 1749+ foreach( $triplets as $file )
 1750+ if( $result[$file[0]] )
 1751+ $filteredTriplets[] = $file;
 1752+ return $filteredTriplets;
 1753+ }
 1754+
 1755+ /**
 1756+ * Removes non-existent files from a cleanup batch.
 1757+ */
 1758+ function removeNonexistentFromCleanup( $batch ) {
 1759+ $files = $newBatch = array();
 1760+ $repo = $this->file->repo;
 1761+ foreach( $batch as $file ) {
 1762+ $files[$file] = $repo->getVirtualUrl( 'deleted' ) . '/' .
 1763+ rawurlencode( $repo->getDeletedHashPath( $file ) . $file );
 1764+ }
 1765+
 1766+ $result = $repo->fileExistsBatch( $files, FSRepo::FILES_ONLY );
 1767+ foreach( $batch as $file )
 1768+ if( $result[$file] )
 1769+ $newBatch[] = $file;
 1770+ return $newBatch;
 1771+ }
 1772+
 1773+ /**
17111774 * Delete unused files in the deleted zone.
17121775 * This should be called from outside the transaction in which execute() was called.
17131776 */
@@ -1714,6 +1777,7 @@
17151778 if ( !$this->cleanupBatch ) {
17161779 return $this->file->repo->newGood();
17171780 }
 1781+ $this->cleanupBatch = $this->removeNonexistentFromCleanup( $this->cleanupBatch );
17181782 $status = $this->file->repo->cleanupDeletedBatch( $this->cleanupBatch );
17191783 return $status;
17201784 }
@@ -1793,11 +1857,7 @@
17941858 $status = $repo->newGood();
17951859 $triplets = $this->getMoveTriplets();
17961860
1797 - $statusPreCheck = $this->checkFileExistence( 0 );
1798 - if( !$statusPreCheck->isOk() ) {
1799 - wfDebugLog( 'imagemove', "Move of {$this->file->name} aborted due to pre-move file existence check failure" );
1800 - return $statusPreCheck;
1801 - }
 1861+ $triplets = $this->removeNonexistentFiles( $triplets );
18021862 $statusDb = $this->doDBUpdates();
18031863 wfDebugLog( 'imagemove', "Renamed {$this->file->name} in database: {$statusDb->successCount} successes, {$statusDb->failCount} failures" );
18041864 $statusMove = $repo->storeBatch( $triplets, FSRepo::DELETE_SOURCE );
@@ -1805,12 +1865,6 @@
18061866 if( !$statusMove->isOk() ) {
18071867 wfDebugLog( 'imagemove', "Error in moving files: " . $statusMove->getWikiText() );
18081868 $this->db->rollback();
1809 - } else {
1810 - $statusPostCheck = $this->checkFileExistence( 1 );
1811 - if( !$statusPostCheck->isOk() ) {
1812 - // This clearly mustn't have happend. FSRepo::storeBatch should have given out an error in that case.
1813 - wfDebugLog( 'imagemove', "ATTENTION! Move of {$this->file->name} has some files missing, while storeBatch() reported success" );
1814 - }
18151869 }
18161870
18171871 $status->merge( $statusDb );
@@ -1874,21 +1928,20 @@
18751929 }
18761930
18771931 /*
1878 - * Checks file existence.
1879 - * Set $key = 0 for source files check
1880 - * and $key = 1 for destination files check.
 1932+ * Removes non-existent files from move batch.
18811933 */
1882 - function checkFileExistence( $key = 0 ) {
 1934+ function removeNonexistentFiles( $triplets ) {
18831935 $files = array();
1884 - foreach( array_merge( array( $this->cur ), $this->olds ) as $file )
1885 - $files[$file[$key]] = $this->file->repo->getVirtualUrl() . '/public/' . rawurlencode( $file[$key] );
 1936+ foreach( $triplets as $file )
 1937+ $files[$file[0]] = $file[0];
18861938 $result = $this->file->repo->fileExistsBatch( $files, FSRepo::FILES_ONLY );
1887 - $status = $this->file->repo->newGood();
1888 - foreach( $result as $filename => $exists )
1889 - if( !$exists ) {
1890 - wfDebugLog( 'imagemove', "File {$filename} does not exist" );
1891 - $status->fatal( 'filenotfound', $filename );
 1939+ $filteredTriplets = array();
 1940+ foreach( $triplets as $file )
 1941+ if( $result[$file[0]] ) {
 1942+ $filteredTriplets[] = $file;
 1943+ } else {
 1944+ wfDebugLog( 'imagemove', "File {$file[0]} does not exist" );
18921945 }
1893 - return $status;
 1946+ return $filteredTriplets;
18941947 }
18951948 }
Index: trunk/phase3/includes/filerepo/File.php
@@ -306,6 +306,9 @@
307307 * or if it is an SVG image and SVG conversion is enabled.
308308 */
309309 function canRender() {
 310+ if( $this->isMissing() ) {
 311+ return false;
 312+ }
310313 if ( !isset( $this->canRender ) ) {
311314 $this->canRender = $this->getHandler() && $this->handler->canRender( $this );
312315 }
@@ -1259,6 +1262,10 @@
12601263 function redirectedFrom( $from ) {
12611264 $this->redirected = $from;
12621265 }
 1266+
 1267+ function isMissing() {
 1268+ return false;
 1269+ }
12631270 }
12641271 /**
12651272 * Aliases for backwards compatibility with 1.6
Index: trunk/phase3/RELEASE-NOTES
@@ -149,7 +149,7 @@
150150 * (bug 17714) Limited TIFF upload support now built in if 'tif' extension is
151151 enabled. Image width and height are now recognized, and when using
152152 ImageMagick, optional flattening to PNG or JPEG for inline display can be
153 - enabled by setting $wgTiffThumbnailType
 153+ enabled by setting $wgTiffThumbnailTypezz
154154 * Renamed two input IDs on Special:Log from 'page' and 'user' to 'mw-log-page'
155155 and 'mw-log-user', respectively
156156 * Added $wgInvalidUsernameCharacters to disallow certain characters in
@@ -179,8 +179,8 @@
180180 * (bug 16950) Show move log when viewing/creating a deleted page
181181 * (bug 18242) Show the Subversion revision number per extensions in
182182 Special:Version
 183+* (bug 18420) Missing file revisions are handled gracefully now
183184
184 -
185185 === Bug fixes in 1.15 ===
186186 * (bug 16968) Special:Upload no longer throws useless warnings.
187187 * (bug 17000) Special:RevisionDelete now checks if the database is locked

Status & tagging log