/** @var bool Whether the row was upgraded on load */
private $upgraded;
+ /** @var bool Whether the row was scheduled to upgrade on load */
+ private $upgrading;
+
/** @var bool True if the image row is locked */
private $locked;
*/
function maybeUpgradeRow() {
global $wgUpdateCompatibleMetadata;
- if ( wfReadOnly() ) {
+
+ if ( wfReadOnly() || $this->upgrading ) {
return;
}
$upgrade = false;
- if ( is_null( $this->media_type ) ||
- $this->mime == 'image/svg'
- ) {
+ if ( is_null( $this->media_type ) || $this->mime == 'image/svg' ) {
$upgrade = true;
} else {
$handler = $this->getHandler();
if ( $handler ) {
$validity = $handler->isMetadataValid( $this, $this->getMetadata() );
- if ( $validity === MediaHandler::METADATA_BAD
- || ( $validity === MediaHandler::METADATA_COMPATIBLE && $wgUpdateCompatibleMetadata )
- ) {
+ if ( $validity === MediaHandler::METADATA_BAD ) {
$upgrade = true;
+ } elseif ( $validity === MediaHandler::METADATA_COMPATIBLE ) {
+ $upgrade = $wgUpdateCompatibleMetadata;
}
}
}
if ( $upgrade ) {
- try {
- $this->upgradeRow();
- } catch ( LocalFileLockError $e ) {
- // let the other process handle it (or do it next time)
- }
- $this->upgraded = true; // avoid rework/retries
+ $this->upgrading = true;
+ // Defer updates unless in auto-commit CLI mode
+ DeferredUpdates::addCallableUpdate( function() {
+ $this->upgrading = false; // avoid duplicate updates
+ try {
+ $this->upgradeRow();
+ } catch ( LocalFileLockError $e ) {
+ // let the other process handle it (or do it next time)
+ }
+ } );
}
}
+ /**
+ * @return bool Whether upgradeRow() ran for this object
+ */
function getUpgraded() {
return $this->upgraded;
}
$this->invalidateCache();
$this->unlock(); // done
-
+ $this->upgraded = true; // avoid rework/retries
}
/**
DeferredUpdates::addUpdate( new CdnCacheUpdate( $urls ), DeferredUpdates::PRESEND );
}
+ /**
+ * Prerenders a configurable set of thumbnails
+ *
+ * @since 1.28
+ */
+ public function prerenderThumbnails() {
+ global $wgUploadThumbnailRenderMap;
+
+ $jobs = [];
+
+ $sizes = $wgUploadThumbnailRenderMap;
+ rsort( $sizes );
+
+ foreach ( $sizes as $size ) {
+ if ( $this->isVectorized() || $this->getWidth() > $size ) {
+ $jobs[] = new ThumbnailRenderJob(
+ $this->getTitle(),
+ [ 'transformParams' => [ 'width' => $size ] ]
+ );
+ }
+ }
+
+ if ( $jobs ) {
+ JobQueueGroup::singleton()->lazyPush( $jobs );
+ }
+ }
+
/**
* Delete a list of thumbnails visible at urls
* @param string $dir Base dir of the files.
# Update backlink pages pointing to this title if created
LinksUpdate::queueRecursiveJobsForTable( $this->getTitle(), 'imagelinks' );
}
+
+ $this->prerenderThumbnails();
}
- )
+ ),
+ DeferredUpdates::PRESEND
);
if ( !$reupload ) {
}
protected function doDBInserts() {
+ $now = time();
$dbw = $this->file->repo->getMasterDB();
- $encTimestamp = $dbw->addQuotes( $dbw->timestamp() );
+ $encTimestamp = $dbw->addQuotes( $dbw->timestamp( $now ) );
$encUserId = $dbw->addQuotes( $this->user->getId() );
$encReason = $dbw->addQuotes( $this->reason );
$encGroup = $dbw->addQuotes( 'deleted' );
}
if ( $deleteCurrent ) {
- $concat = $dbw->buildConcat( [ "img_sha1", $encExt ] );
- $where = [ 'img_name' => $this->file->getName() ];
- $dbw->insertSelect( 'filearchive', 'image',
+ $dbw->insertSelect(
+ 'filearchive',
+ 'image',
[
'fa_storage_group' => $encGroup,
'fa_storage_key' => $dbw->conditional(
[ 'img_sha1' => '' ],
$dbw->addQuotes( '' ),
- $concat
+ $dbw->buildConcat( [ "img_sha1", $encExt ] )
),
'fa_deleted_user' => $encUserId,
'fa_deleted_timestamp' => $encTimestamp,
'fa_user' => 'img_user',
'fa_user_text' => 'img_user_text',
'fa_timestamp' => 'img_timestamp',
- 'fa_sha1' => 'img_sha1',
- ], $where, __METHOD__ );
+ 'fa_sha1' => 'img_sha1'
+ ],
+ [ 'img_name' => $this->file->getName() ],
+ __METHOD__
+ );
}
if ( count( $oldRels ) ) {
- $concat = $dbw->buildConcat( [ "oi_sha1", $encExt ] );
- $where = [
- 'oi_name' => $this->file->getName(),
- 'oi_archive_name' => array_keys( $oldRels ) ];
- $dbw->insertSelect( 'filearchive', 'oldimage',
+ $res = $dbw->select(
+ 'oldimage',
+ OldLocalFile::selectFields(),
[
- 'fa_storage_group' => $encGroup,
- 'fa_storage_key' => $dbw->conditional(
- [ 'oi_sha1' => '' ],
- $dbw->addQuotes( '' ),
- $concat
- ),
- 'fa_deleted_user' => $encUserId,
- 'fa_deleted_timestamp' => $encTimestamp,
- 'fa_deleted_reason' => $encReason,
- 'fa_deleted' => $this->suppress ? $bitfield : 'oi_deleted',
-
- 'fa_name' => 'oi_name',
- 'fa_archive_name' => 'oi_archive_name',
- 'fa_size' => 'oi_size',
- 'fa_width' => 'oi_width',
- 'fa_height' => 'oi_height',
- 'fa_metadata' => 'oi_metadata',
- 'fa_bits' => 'oi_bits',
- 'fa_media_type' => 'oi_media_type',
- 'fa_major_mime' => 'oi_major_mime',
- 'fa_minor_mime' => 'oi_minor_mime',
- 'fa_description' => 'oi_description',
- 'fa_user' => 'oi_user',
- 'fa_user_text' => 'oi_user_text',
- 'fa_timestamp' => 'oi_timestamp',
- 'fa_sha1' => 'oi_sha1',
- ], $where, __METHOD__ );
+ 'oi_name' => $this->file->getName(),
+ 'oi_archive_name' => array_keys( $oldRels )
+ ],
+ __METHOD__,
+ [ 'FOR UPDATE' ]
+ );
+ $rowsInsert = [];
+ foreach ( $res as $row ) {
+ $rowsInsert[] = [
+ // Deletion-specific fields
+ 'fa_storage_group' => 'deleted',
+ 'fa_storage_key' => ( $row->oi_sha1 === '' )
+ ? ''
+ : "{$row->oi_sha1}{$dotExt}",
+ 'fa_deleted_user' => $this->user->getId(),
+ 'fa_deleted_timestamp' => $dbw->timestamp( $now ),
+ 'fa_deleted_reason' => $this->reason,
+ // Counterpart fields
+ 'fa_deleted' => $this->suppress ? $bitfield : $row->oi_deleted,
+ 'fa_name' => $row->oi_name,
+ 'fa_archive_name' => $row->oi_archive_name,
+ 'fa_size' => $row->oi_size,
+ 'fa_width' => $row->oi_width,
+ 'fa_height' => $row->oi_height,
+ 'fa_metadata' => $row->oi_metadata,
+ 'fa_bits' => $row->oi_bits,
+ 'fa_media_type' => $row->oi_media_type,
+ 'fa_major_mime' => $row->oi_major_mime,
+ 'fa_minor_mime' => $row->oi_minor_mime,
+ 'fa_description' => $row->oi_description,
+ 'fa_user' => $row->oi_user,
+ 'fa_user_text' => $row->oi_user_text,
+ 'fa_timestamp' => $row->oi_timestamp,
+ 'fa_sha1' => $row->oi_sha1
+ ];
+ }
+
+ $dbw->insert( 'filearchive', $rowsInsert, __METHOD__ );
}
}
// The live (current) version cannot be hidden!
if ( !$this->unsuppress && $row->fa_deleted ) {
- $storeBatch[] = [ $deletedUrl, 'public', $destRel ];
- $this->cleanupBatch[] = $row->fa_storage_key;
+ $status->fatal( 'undeleterevdel' );
+ $this->file->unlock();
+ return $status;
}
} else {
$archiveName = $row->fa_archive_name;