$this->dataLoaded = false;
}
-
+
/**
* Normalize a file extension to the common form, and ensure it's clean.
* Extensions with non-alphanumeric characters will be discarded.
return '';
}
}
-
+
/**
* Get the memcached keys
* Returns an array, first element is the local cache key, second is the shared cache key, if there is one
}
wfProfileOut( __METHOD__ );
}
-
+
/**
* Split an internet media type into its two components; if not
* a two-part name, set the minor type to 'unknown'.
*/
function validateThumbParams( &$width, &$height ) {
global $wgSVGMaxSize, $wgMaxImageArea;
-
+
$this->load();
if ( ! $this->exists() )
# If there is no image, there will be no thumbnail
return false;
}
-
+
$width = intval( $width );
-
+
# Sanity check $width
if( $width <= 0 || $this->width <= 0) {
# BZZZT
$height = round( $this->height * $width / $this->width );
return true;
}
-
+
/**
* Create a thumbnail of the image having the specified width.
* The thumbnail will not be created if the width is larger than the
wfProfileOut( __METHOD__ );
return $thumb;
}
-
+
list( $isScriptUrl, $url ) = $this->thumbUrl( $width );
if ( $isScriptUrl && $useScript ) {
// Use thumb.php to render the image
@unlink( $thumbDir );
}
wfMkdirParents( $thumbDir );
-
+
$oldThumbPath = wfDeprecatedThumbDir( $thumbName, 'thumb', $this->fromSharedDirectory ).
'/'.$thumbName;
$done = false;
$err = false;
$cmd = "";
$retval = 0;
-
+
if( $this->mime === "image/svg" ) {
#Right now we have only SVG
} elseif ( $wgUseImageMagick ) {
# use ImageMagick
-
+
if ( $this->mime == 'image/jpeg' ) {
$quality = "-quality 80"; // 80%
} elseif ( $this->mime == 'image/png' ) {
# Specify white background color, will be used for transparent images
# in Internet Explorer/Windows instead of default black.
-
+
# Note, we specify "-size {$width}" and NOT "-size {$width}x{$height}".
# It seems that ImageMagick has a bug wherein it produces thumbnails of
# the wrong size in the second case.
-
+
$cmd = wfEscapeShellArg($wgImageMagickConvertCommand) .
" {$quality} -background white -size {$width} ".
wfEscapeShellArg($this->imagePath) .
#
# First find out what kind of file this is, and select the correct
# input routine for this.
-
+
$typemap = array(
'image/gif' => array( 'imagecreatefromgif', 'palette', 'imagegif' ),
'image/jpeg' => array( 'imagecreatefromjpeg', 'truecolor', array( &$this, 'imageJpegWrapper' ) ),
if ( is_dir( $dir ) ) {
$handle = opendir( $dir );
-
+
if ( $handle ) {
while ( false !== ( $file = readdir($handle) ) ) {
if ( $file{0} != '.' ) {
wfPurgeSquidServers( $urls );
}
}
-
+
/**
* Purge the image description page, but don't go after
* pages using the image. Use when modifying file history
$page->invalidateCache();
$page->purgeSquid();
}
-
+
/**
* Purge metadata and all affected pages when the image is created,
* deleted, or majorly updated. A set of additional URLs may be
// Delete thumbnails and refresh image metadata cache
$this->purgeCache();
$this->purgeDescription();
-
+
// Purge cache of all pages using this image
$update = new HTMLCacheUpdate( $this->getTitle(), 'imagelinks' );
$update->doUpdate();
wfProfileOut( __METHOD__ );
return $retVal;
}
-
+
/**
* Retrive Exif data from the file and prune unrecognized tags
* and/or tags with invalid contents
*/
private function retrieveExifData( $filename ) {
global $wgShowEXIF;
-
+
/*
if ( $this->getMimeType() !== "image/jpeg" )
return array();
$exif = new Exif( $filename );
return $exif->getFilteredData();
}
-
+
return array();
}
function isLocal() {
return !$this->fromSharedDirectory;
}
-
+
/**
* Was this image ever deleted from the wiki?
*
$title = Title::makeTitle( NS_IMAGE, $this->name );
return ( $title->isDeleted() > 0 );
}
-
+
/**
* Delete all versions of the image.
*
function delete( $reason ) {
$transaction = new FSTransaction();
$urlArr = array( $this->getURL() );
-
+
if( !FileStore::lock() ) {
wfDebug( __METHOD__.": failed to acquire file store lock, aborting\n" );
return false;
}
-
+
try {
$dbw = wfGetDB( DB_MASTER );
$dbw->begin();
-
+
// Delete old versions
$result = $dbw->select( 'oldimage',
array( 'oi_archive_name' ),
array( 'oi_name' => $this->name ) );
-
+
while( $row = $dbw->fetchObject( $result ) ) {
$oldName = $row->oi_archive_name;
-
+
$transaction->add( $this->prepareDeleteOld( $oldName, $reason ) );
-
+
// We'll need to purge this URL from caches...
$urlArr[] = wfImageArchiveUrl( $oldName );
}
$dbw->freeResult( $result );
-
+
// And the current version...
$transaction->add( $this->prepareDeleteCurrent( $reason ) );
-
+
$dbw->immediateCommit();
} catch( MWException $e ) {
wfDebug( __METHOD__.": db error, rolling back file transactions\n" );
FileStore::unlock();
throw $e;
}
-
+
wfDebug( __METHOD__.": deleted db items, applying file transactions\n" );
$transaction->commit();
FileStore::unlock();
-
+
// Update site_stats
$site_stats = $dbw->tableName( 'site_stats' );
$dbw->query( "UPDATE $site_stats SET ss_images=ss_images-1", __METHOD__ );
-
+
$this->purgeEverything( $urlArr );
-
+
return true;
}
-
-
+
+
/**
* Delete an old version of the image.
*
function deleteOld( $archiveName, $reason ) {
$transaction = new FSTransaction();
$urlArr = array();
-
+
if( !FileStore::lock() ) {
wfDebug( __METHOD__.": failed to acquire file store lock, aborting\n" );
return false;
}
-
+
$transaction = new FSTransaction();
try {
$dbw = wfGetDB( DB_MASTER );
FileStore::unlock();
throw $e;
}
-
+
wfDebug( __METHOD__.": deleted db items, applying file transaction\n" );
$transaction->commit();
FileStore::unlock();
-
+
$this->purgeDescription();
// Squid purging
}
return true;
}
-
+
/**
* Delete the current version of a file.
* May throw a database error.
*/
private function prepareDeleteVersion( $path, $reason, $table, $fieldMap, $where, $fname ) {
global $wgUser, $wgSaveDeletedFiles;
-
+
// Dupe the file into the file store
if( file_exists( $path ) ) {
if( $wgSaveDeletedFiles ) {
$group = 'deleted';
-
+
$store = FileStore::get( $group );
$key = FileStore::calculateKey( $path, $this->extension );
$transaction = $store->insert( $key, $path,
$key = null;
$transaction = new FSTransaction(); // empty
}
-
+
if( $transaction === false ) {
// Fail to restore?
wfDebug( __METHOD__.": import to file store failed, aborting\n" );
throw new MWException( "Could not archive and delete file $path" );
return false;
}
-
+
$dbw = wfGetDB( DB_MASTER );
$storageMap = array(
'fa_storage_group' => $dbw->addQuotes( $group ),
'fa_storage_key' => $dbw->addQuotes( $key ),
-
+
'fa_deleted_user' => $dbw->addQuotes( $wgUser->getId() ),
'fa_deleted_timestamp' => $dbw->timestamp(),
'fa_deleted_reason' => $dbw->addQuotes( $reason ) );
$allFields = array_merge( $storageMap, $fieldMap );
-
+
try {
if( $wgSaveDeletedFiles ) {
$dbw->insertSelect( 'filearchive', $table, $allFields, $where, $fname );
$transaction->rollback();
throw $e;
}
-
+
return $transaction;
}
-
+
/**
* Restore all or specified deleted revisions to the given file.
* Permissions and logging are left to the caller.
wfDebug( __METHOD__." could not acquire filestore lock\n" );
return false;
}
-
+
$transaction = new FSTransaction();
try {
$dbw = wfGetDB( DB_MASTER );
$dbw->begin();
-
+
// Re-confirm whether this image presently exists;
// if no we'll need to create an image record for the
// first item we restore.
$exists = $dbw->selectField( 'image', '1',
array( 'img_name' => $this->name ),
__METHOD__ );
-
+
// Fetch all or selected archived revisions for the file,
// sorted from the most recent to the oldest.
$conditions = array( 'fa_name' => $this->name );
if( $versions ) {
$conditions['fa_id'] = $versions;
}
-
+
$result = $dbw->select( 'filearchive', '*',
$conditions,
__METHOD__,
array( 'ORDER BY' => 'fa_timestamp DESC' ) );
-
+
if( $dbw->numRows( $result ) < count( $versions ) ) {
// There's some kind of conflict or confusion;
// we can't restore everything we were asked to.
FileStore::unlock();
return true;
}
-
+
$revisions = 0;
while( $row = $dbw->fetchObject( $result ) ) {
$revisions++;
wfDebug( __METHOD__.": skipping row with no file.\n" );
continue;
}
-
+
if( $revisions == 1 && !$exists ) {
$destDir = wfImageDir( $row->fa_name );
if ( !is_dir( $destDir ) ) {
wfMkdirParents( $destDir );
}
$destPath = $destDir . DIRECTORY_SEPARATOR . $row->fa_name;
-
+
// We may have to fill in data if this was originally
// an archived file revision.
if( is_null( $row->fa_metadata ) ) {
$tempFile = $store->filePath( $row->fa_storage_key );
$metadata = serialize( $this->retrieveExifData( $tempFile ) );
-
+
$magic = MimeMagic::singleton();
$mime = $magic->guessMimeType( $tempFile, true );
$media_type = $magic->getMediaType( $tempFile, $mime );
$minor_mime = $row->fa_minor_mime;
$media_type = $row->fa_media_type;
}
-
+
$table = 'image';
$fields = array(
'img_name' => $row->fa_name,
wfMkdirParents( $destDir );
}
$destPath = $destDir . DIRECTORY_SEPARATOR . $archiveName;
-
+
$table = 'oldimage';
$fields = array(
'oi_name' => $row->fa_name,
'oi_user_text' => $row->fa_user_text,
'oi_timestamp' => $row->fa_timestamp );
}
-
+
$dbw->insert( $table, $fields, __METHOD__ );
/// @fixme this delete is not totally safe, potentially
$dbw->delete( 'filearchive',
array( 'fa_id' => $row->fa_id ),
__METHOD__ );
-
+
// Check if any other stored revisions use this file;
// if so, we shouldn't remove the file from the deletion
// archives so they will still work.
} else {
$flags = 0;
}
-
+
$transaction->add( $store->export( $row->fa_storage_key,
$destPath, $flags ) );
}
-
+
$dbw->immediateCommit();
} catch( MWException $e ) {
wfDebug( __METHOD__." caught error, aborting\n" );
$transaction->rollback();
throw $e;
}
-
+
$transaction->commit();
FileStore::unlock();
-
+
if( $revisions > 0 ) {
if( !$exists ) {
wfDebug( __METHOD__." restored $revisions items, creating a new current\n" );
-
+
// Update site_stats
$site_stats = $dbw->tableName( 'site_stats' );
$dbw->query( "UPDATE $site_stats SET ss_images=ss_images+1", __METHOD__ );
-
+
$this->purgeEverything();
} else {
wfDebug( __METHOD__." restored $revisions as archived versions\n" );
$this->purgeDescription();
}
}
-
+
return $revisions;
}
if ( isset( $this->multiPageXML ) ) {
return true;
}
-
+
#
# Check for files uploaded prior to DJVU support activation,
# or damaged.
return null;
}
}
-
+
} //class
/**