/**#@-*/
+ protected $repoClass = 'LocalRepo';
+
/**
* Create a LocalFile from a title
* Do not call this except from inside a repo class.
* Create a LocalFile from a SHA-1 key
* Do not call this except from inside a repo class.
*
- * @param $sha1 string
+ * @param $sha1 string base-36 SHA-1
* @param $repo LocalRepo
- * @param $timestamp string
+ * @param string|bool $timestamp MW_timestamp (optional)
*
- * @return LocalFile
+ * @return bool|LocalFile
*/
static function newFromKey( $sha1, $repo, $timestamp = false ) {
- $conds = array( 'img_sha1' => $sha1 );
+ $dbr = $repo->getSlaveDB();
+ $conds = array( 'img_sha1' => $sha1 );
if ( $timestamp ) {
- $conds['img_timestamp'] = $timestamp;
+ $conds['img_timestamp'] = $dbr->timestamp( $timestamp );
}
- $dbr = $repo->getSlaveDB();
$row = $dbr->selectRow( 'image', self::selectFields(), $conds, __METHOD__ );
-
if ( $row ) {
return self::newFromRow( $row, $repo );
} else {
* Do not call this except from inside a repo class.
*/
function __construct( $title, $repo ) {
- if ( !is_object( $title ) ) {
- throw new MWException( __CLASS__ . ' constructor given bogus title.' );
- }
-
parent::__construct( $title, $repo );
$this->metadata = '';
$this->historyLine = 0;
$this->historyRes = null;
$this->dataLoaded = false;
+
+ $this->assertRepoDefined();
+ $this->assertTitleDefined();
}
/**
/**
* Get all thumbnail names previously generated for this file
+ * @param $archiveName string|false Name of an archive file
+ * @return array first element is the base dir, then files in that base dir.
*/
- function getThumbnails() {
+ function getThumbnails( $archiveName = false ) {
$this->load();
+ if ( $archiveName ) {
+ $dir = $this->getArchiveThumbPath( $archiveName );
+ } else {
+ $dir = $this->getThumbPath();
+ }
$files = array();
- $dir = $this->getThumbPath();
+ $files[] = $dir;
if ( is_dir( $dir ) ) {
$handle = opendir( $dir );
}
/**
- * Delete cached transformed files
+ * Delete cached transformed files for archived files
+ * @param $archiveName string name of the archived file
+ */
+ function purgeOldThumbnails( $archiveName ) {
+ global $wgUseSquid;
+ // Get a list of old thumbnails and URLs
+ $files = $this->getThumbnails( $archiveName );
+ $dir = array_shift( $files );
+ $this->purgeThumbList( $dir, $files );
+
+ // Directory should be empty, delete it too. This will probably suck on
+ // something like NFS or if the directory isn't actually empty, so hide
+ // the warnings :D
+ wfSuppressWarnings();
+ if( !rmdir( $dir ) ) {
+ wfDebug( __METHOD__ . ": unable to remove archive directory: $dir\n" );
+ }
+ wfRestoreWarnings();
+
+ // Purge any custom thumbnail caches
+ wfRunHooks( 'LocalFilePurgeThumbnails', array( $this, 'archive' ) );
+
+ // Purge the squid
+ if ( $wgUseSquid ) {
+ $urls = array();
+ foreach( $files as $file ) {
+ $urls[] = $this->getArchiveThumbUrl( $archiveName, $file );
+ }
+ SquidUpdate::purge( $urls );
+ }
+ }
+
+
+ /**
+ * Delete cached transformed files for the current version only.
*/
function purgeThumbnails() {
- global $wgUseSquid, $wgExcludeFromThumbnailPurge;
+ global $wgUseSquid;
// Delete thumbnails
$files = $this->getThumbnails();
- $dir = $this->getThumbPath();
- $urls = array();
+ $dir = array_shift( $files );
+ $this->purgeThumbList( $dir, $files );
- foreach ( $files as $file ) {
- // Only remove files not in the $wgExcludeFromThumbnailPurge configuration variable
- $ext = pathinfo( "$dir/$file", PATHINFO_EXTENSION );
- if ( in_array( $ext, $wgExcludeFromThumbnailPurge ) ) {
- continue;
+ // Purge any custom thumbnail caches
+ wfRunHooks( 'LocalFilePurgeThumbnails', array( $this, 'current' ) );
+
+ // Purge the squid
+ if ( $wgUseSquid ) {
+ $urls = array();
+ foreach( $files as $file ) {
+ $urls[] = $this->getThumbUrl( $file );
}
+ SquidUpdate::purge( $urls );
+ }
+ }
+ /**
+ * Delete a list of thumbnails visible at urls
+ * @param $dir string base dir of the files.
+ * @param $files array of strings: relative filenames (to $dir)
+ */
+ protected function purgeThumbList($dir, $files) {
+ wfDebug( __METHOD__ . ": " . var_export( $files, true ) . "\n" );
+ foreach ( $files as $file ) {
# Check that the base file name is part of the thumb name
# This is a basic sanity check to avoid erasing unrelated directories
if ( strpos( $file, $this->getName() ) !== false ) {
- $url = $this->getThumbUrl( $file );
- $urls[] = $url;
wfSuppressWarnings();
unlink( "$dir/$file" );
wfRestoreWarnings();
}
}
-
- // Purge the squid
- if ( $wgUseSquid ) {
- SquidUpdate::purge( $urls );
- }
}
/** purgeDescription inherited */
}
}
- /** getFullPath inherited */
/** getHashPath inherited */
/** getRel inherited */
/** getUrlRel inherited */
return $status;
}
+ /**
+ * Record a file upload in the upload log and the image table
+ */
+ function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '',
+ $watch = false, $timestamp = false )
+ {
+ $pageText = SpecialUpload::getInitialPageText( $desc, $license, $copyStatus, $source );
+
+ if ( !$this->recordUpload2( $oldver, $desc, $pageText ) ) {
+ return false;
+ }
+
+ if ( $watch ) {
+ global $wgUser;
+ $wgUser->addWatch( $this->getTitle() );
+ }
+ return true;
+ }
+
/**
* Record a file upload in the upload log and the image table
*/
} else {
# This is a new file
# Update the image count
- $site_stats = $dbw->tableName( 'site_stats' );
- $dbw->query( "UPDATE $site_stats SET ss_images=ss_images+1", __METHOD__ );
+ $dbw->begin( __METHOD__ );
+ $dbw->update(
+ 'site_stats',
+ array( 'ss_images = ss_images+1' ),
+ '*',
+ __METHOD__
+ );
+ $dbw->commit( __METHOD__ );
}
$descTitle = $this->getTitle();
array( 'oi_name' => $this->getName() ) );
foreach ( $result as $row ) {
$batch->addOld( $row->oi_archive_name );
+ $this->purgeOldThumbnails( $row->oi_archive_name );
}
$status = $batch->execute();
$batch = new LocalFileDeleteBatch( $this, $reason, $suppress );
$batch->addOld( $archiveName );
+ $this->purgeOldThumbnails( $archiveName );
$status = $batch->execute();
$this->unlock();
* @ingroup FileRepo
*/
class LocalFileMoveBatch {
- var $file, $cur, $olds, $oldCount, $archive, $target, $db;
+
+ /**
+ * @var File
+ */
+ var $file;
+
+ /**
+ * @var Title
+ */
+ var $target;
+
+ var $cur, $olds, $oldCount, $archive, $db;
function __construct( File $file, Title $target ) {
$this->file = $file;
// 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" );
+ 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 );
$this->db->begin();
$statusDb = $this->doDBUpdates();
- wfDebugLog( 'imagemove', "Renamed {$this->file->name} in database: {$statusDb->successCount} successes, {$statusDb->failCount} failures" );
+ wfDebugLog( 'imagemove', "Renamed {$this->file->getName()} 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
// $move: (oldRelativePath, newRelativePath)
$srcUrl = $this->file->repo->getVirtualUrl() . '/public/' . rawurlencode( $move[0] );
$triplets[] = array( $srcUrl, 'public', $move[1] );
- wfDebugLog( 'imagemove', "Generated move triplet for {$this->file->name}: {$srcUrl} :: public :: {$move[1]}" );
+ wfDebugLog( 'imagemove', "Generated move triplet for {$this->file->getName()}: {$srcUrl} :: public :: {$move[1]}" );
}
return $triplets;