"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "includes/filerepo/file/LocalFile.php" between
mediawiki-1.31.1.tar.gz and mediawiki-1.32.0.tar.gz

About: MediaWiki is a wiki engine (the collaborative editing software that runs for e.g. Wikipedia, the free encyclopedia).

LocalFile.php  (mediawiki-1.31.1):LocalFile.php  (mediawiki-1.32.0)
skipping to change at line 66 skipping to change at line 66
/** @var int Image height */ /** @var int Image height */
protected $height; protected $height;
/** @var int Returned by getimagesize (loadFromXxx) */ /** @var int Returned by getimagesize (loadFromXxx) */
protected $bits; protected $bits;
/** @var string MEDIATYPE_xxx (bitmap, drawing, audio...) */ /** @var string MEDIATYPE_xxx (bitmap, drawing, audio...) */
protected $media_type; protected $media_type;
/** @var string MIME type, determined by MimeMagic::guessMimeType */ /** @var string MIME type, determined by MimeAnalyzer::guessMimeType */
protected $mime; protected $mime;
/** @var int Size in bytes (loadFromXxx) */ /** @var int Size in bytes (loadFromXxx) */
protected $size; protected $size;
/** @var string Handler-specific metadata */ /** @var string Handler-specific metadata */
protected $metadata; protected $metadata;
/** @var string SHA-1 base 36 content hash */ /** @var string SHA-1 base 36 content hash */
protected $sha1; protected $sha1;
skipping to change at line 204 skipping to change at line 204
/** /**
* Fields in the image table * Fields in the image table
* @deprecated since 1.31, use self::getQueryInfo() instead. * @deprecated since 1.31, use self::getQueryInfo() instead.
* @return string[] * @return string[]
*/ */
static function selectFields() { static function selectFields() {
global $wgActorTableSchemaMigrationStage; global $wgActorTableSchemaMigrationStage;
wfDeprecated( __METHOD__, '1.31' ); wfDeprecated( __METHOD__, '1.31' );
if ( $wgActorTableSchemaMigrationStage > MIGRATION_WRITE_BOTH ) { if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
// If code is using this instead of self::getQueryInfo(), there's a // If code is using this instead of self::getQueryInfo(), there's a
// decent chance it's going to try to directly access // decent chance it's going to try to directly access
// $row->img_user or $row->img_user_text and we can't giv e it // $row->img_user or $row->img_user_text and we can't giv e it
// useful values here once those aren't being written any more. // useful values here once those aren't being used anymor e.
throw new BadMethodCallException( throw new BadMethodCallException(
'Cannot use ' . __METHOD__ . ' when $wgActorTable 'Cannot use ' . __METHOD__
SchemaMigrationStage > MIGRATION_WRITE_BOTH' . ' when $wgActorTableSchemaMigrationStag
e has SCHEMA_COMPAT_READ_NEW'
); );
} }
return [ return [
'img_name', 'img_name',
'img_size', 'img_size',
'img_width', 'img_width',
'img_height', 'img_height',
'img_metadata', 'img_metadata',
'img_bits', 'img_bits',
'img_media_type', 'img_media_type',
'img_major_mime', 'img_major_mime',
'img_minor_mime', 'img_minor_mime',
'img_user', 'img_user',
'img_user_text', 'img_user_text',
'img_actor' => $wgActorTableSchemaMigrationStage > MIGRAT ION_OLD ? 'img_actor' : 'NULL', 'img_actor' => 'NULL',
'img_timestamp', 'img_timestamp',
'img_sha1', 'img_sha1',
] + CommentStore::getStore()->getFields( 'img_description' ); ] + MediaWikiServices::getInstance()->getCommentStore()->getField s( 'img_description' );
} }
/** /**
* Return the tables, fields, and join conditions to be selected to creat e * Return the tables, fields, and join conditions to be selected to creat e
* a new localfile object. * a new localfile object.
* @since 1.31 * @since 1.31
* @param string[] $options * @param string[] $options
* - omit-lazy: Omit fields that are lazily cached. * - omit-lazy: Omit fields that are lazily cached.
* @return array[] With three keys: * @return array[] With three keys:
* - tables: (string[]) to include in the `$table` to `IDatabase->selec t()` * - tables: (string[]) to include in the `$table` to `IDatabase->selec t()`
* - fields: (string[]) to include in the `$vars` to `IDatabase->select ()` * - fields: (string[]) to include in the `$vars` to `IDatabase->select ()`
* - joins: (array) to include in the `$join_conds` to `IDatabase->sele ct()` * - joins: (array) to include in the `$join_conds` to `IDatabase->sele ct()`
*/ */
public static function getQueryInfo( array $options = [] ) { public static function getQueryInfo( array $options = [] ) {
$commentQuery = CommentStore::getStore()->getJoin( 'img_descripti on' ); $commentQuery = MediaWikiServices::getInstance()->getCommentStore ()->getJoin( 'img_description' );
$actorQuery = ActorMigration::newMigration()->getJoin( 'img_user' ); $actorQuery = ActorMigration::newMigration()->getJoin( 'img_user' );
$ret = [ $ret = [
'tables' => [ 'image' ] + $commentQuery['tables'] + $acto rQuery['tables'], 'tables' => [ 'image' ] + $commentQuery['tables'] + $acto rQuery['tables'],
'fields' => [ 'fields' => [
'img_name', 'img_name',
'img_size', 'img_size',
'img_width', 'img_width',
'img_height', 'img_height',
'img_metadata', 'img_metadata',
'img_bits', 'img_bits',
skipping to change at line 326 skipping to change at line 327
$this->dataLoaded = false; $this->dataLoaded = false;
$this->extraDataLoaded = false; $this->extraDataLoaded = false;
$key = $this->getCacheKey(); $key = $this->getCacheKey();
if ( !$key ) { if ( !$key ) {
$this->loadFromDB( self::READ_NORMAL ); $this->loadFromDB( self::READ_NORMAL );
return; return;
} }
$cache = ObjectCache::getMainWANInstance(); $cache = MediaWikiServices::getInstance()->getMainWANObjectCache( );
$cachedValues = $cache->getWithSetCallback( $cachedValues = $cache->getWithSetCallback(
$key, $key,
$cache::TTL_WEEK, $cache::TTL_WEEK,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $cac he ) { function ( $oldValue, &$ttl, array &$setOpts ) use ( $cac he ) {
$setOpts += Database::getCacheSetOptions( $this-> repo->getReplicaDB() ); $setOpts += Database::getCacheSetOptions( $this-> repo->getReplicaDB() );
$this->loadFromDB( self::READ_NORMAL ); $this->loadFromDB( self::READ_NORMAL );
$fields = $this->getCacheFields( '' ); $fields = $this->getCacheFields( '' );
$cacheVal['fileExists'] = $this->fileExists; $cacheVal['fileExists'] = $this->fileExists;
skipping to change at line 391 skipping to change at line 392
* Purge the file object/metadata cache * Purge the file object/metadata cache
*/ */
public function invalidateCache() { public function invalidateCache() {
$key = $this->getCacheKey(); $key = $this->getCacheKey();
if ( !$key ) { if ( !$key ) {
return; return;
} }
$this->repo->getMasterDB()->onTransactionPreCommitOrIdle( $this->repo->getMasterDB()->onTransactionPreCommitOrIdle(
function () use ( $key ) { function () use ( $key ) {
ObjectCache::getMainWANInstance()->delete( $key ) ; MediaWikiServices::getInstance()->getMainWANObjec tCache()->delete( $key );
}, },
__METHOD__ __METHOD__
); );
} }
/** /**
* Load metadata from the file itself * Load metadata from the file itself
*/ */
function loadFromFile() { function loadFromFile() {
$props = $this->repo->getFileProps( $this->getVirtualUrl() ); $props = $this->repo->getFileProps( $this->getVirtualUrl() );
skipping to change at line 582 skipping to change at line 583
* Decode a row from the database (either object or array) to an array * Decode a row from the database (either object or array) to an array
* with timestamps and MIME types decoded, and the field prefix removed. * with timestamps and MIME types decoded, and the field prefix removed.
* @param object $row * @param object $row
* @param string $prefix * @param string $prefix
* @throws MWException * @throws MWException
* @return array * @return array
*/ */
function decodeRow( $row, $prefix = 'img_' ) { function decodeRow( $row, $prefix = 'img_' ) {
$decoded = $this->unprefixRow( $row, $prefix ); $decoded = $this->unprefixRow( $row, $prefix );
$decoded['description'] = CommentStore::getStore() $decoded['description'] = MediaWikiServices::getInstance()->getCo mmentStore()
->getComment( 'description', (object)$decoded )->text; ->getComment( 'description', (object)$decoded )->text;
$decoded['user'] = User::newFromAnyId( $decoded['user'] = User::newFromAnyId(
isset( $decoded['user'] ) ? $decoded['user'] : null, $decoded['user'] ?? null,
isset( $decoded['user_text'] ) ? $decoded['user_text'] : $decoded['user_text'] ?? null,
null, $decoded['actor'] ?? null
isset( $decoded['actor'] ) ? $decoded['actor'] : null
); );
unset( $decoded['user_text'], $decoded['actor'] ); unset( $decoded['user_text'], $decoded['actor'] );
$decoded['timestamp'] = wfTimestamp( TS_MW, $decoded['timestamp'] ); $decoded['timestamp'] = wfTimestamp( TS_MW, $decoded['timestamp'] );
$decoded['metadata'] = $this->repo->getReplicaDB()->decodeBlob( $ decoded['metadata'] ); $decoded['metadata'] = $this->repo->getReplicaDB()->decodeBlob( $ decoded['metadata'] );
if ( empty( $decoded['major_mime'] ) ) { if ( empty( $decoded['major_mime'] ) ) {
$decoded['mime'] = 'unknown/unknown'; $decoded['mime'] = 'unknown/unknown';
} else { } else {
skipping to change at line 775 skipping to change at line 776
$fields[] = 'fileExists'; $fields[] = 'fileExists';
foreach ( $fields as $field ) { foreach ( $fields as $field ) {
if ( isset( $info[$field] ) ) { if ( isset( $info[$field] ) ) {
$this->$field = $info[$field]; $this->$field = $info[$field];
} }
} }
if ( isset( $info['user'] ) || isset( $info['user_text'] ) || iss et( $info['actor'] ) ) { if ( isset( $info['user'] ) || isset( $info['user_text'] ) || iss et( $info['actor'] ) ) {
$this->user = User::newFromAnyId( $this->user = User::newFromAnyId(
isset( $info['user'] ) ? $info['user'] : null, $info['user'] ?? null,
isset( $info['user_text'] ) ? $info['user_text'] $info['user_text'] ?? null,
: null, $info['actor'] ?? null
isset( $info['actor'] ) ? $info['actor'] : null
); );
} }
// Fix up mime fields // Fix up mime fields
if ( isset( $info['major_mime'] ) ) { if ( isset( $info['major_mime'] ) ) {
$this->mime = "{$info['major_mime']}/{$info['minor_mime'] }"; $this->mime = "{$info['major_mime']}/{$info['minor_mime'] }";
} elseif ( isset( $info['mime'] ) ) { } elseif ( isset( $info['mime'] ) ) {
$this->mime = $info['mime']; $this->mime = $info['mime'];
list( $this->major_mime, $this->minor_mime ) = self::spli tMime( $this->mime ); list( $this->major_mime, $this->minor_mime ) = self::spli tMime( $this->mime );
} }
skipping to change at line 1303 skipping to change at line 1304
* if a new description page is created * if a new description page is created
* @param int|bool $flags Flags for publish() * @param int|bool $flags Flags for publish()
* @param array|bool $props File properties, if known. This can be used t o * @param array|bool $props File properties, if known. This can be used t o
* reduce the upload time when uploading virtual URLs for which the fil e * reduce the upload time when uploading virtual URLs for which the fil e
* info is already known * info is already known
* @param string|bool $timestamp Timestamp for img_timestamp, or false to use the * @param string|bool $timestamp Timestamp for img_timestamp, or false to use the
* current time * current time
* @param User|null $user User object or null to use $wgUser * @param User|null $user User object or null to use $wgUser
* @param string[] $tags Change tags to add to the log entry and page rev ision. * @param string[] $tags Change tags to add to the log entry and page rev ision.
* (This doesn't check $user's permissions.) * (This doesn't check $user's permissions.)
* @param bool $createNullRevision Set to false to avoid creation of a nu
ll revision on file
* upload, see T193621
* @return Status On success, the value member contains the * @return Status On success, the value member contains the
* archive name, or an empty string if it was a new file. * archive name, or an empty string if it was a new file.
*/ */
function upload( $src, $comment, $pageText, $flags = 0, $props = false, function upload( $src, $comment, $pageText, $flags = 0, $props = false,
$timestamp = false, $user = null, $tags = [] $timestamp = false, $user = null, $tags = [],
$createNullRevision = true
) { ) {
if ( $this->getRepo()->getReadOnlyReason() !== false ) { if ( $this->getRepo()->getReadOnlyReason() !== false ) {
return $this->readOnlyFatalStatus(); return $this->readOnlyFatalStatus();
} elseif ( MediaWikiServices::getInstance()->getRevisionStore()-> isReadOnly() ) { } elseif ( MediaWikiServices::getInstance()->getRevisionStore()-> isReadOnly() ) {
// Check this in advance to avoid writing to FileBackend and the file tables, // Check this in advance to avoid writing to FileBackend and the file tables,
// only to fail on insert the revision due to the text st ore being unavailable. // only to fail on insert the revision due to the text st ore being unavailable.
return $this->readOnlyFatalStatus(); return $this->readOnlyFatalStatus();
} }
$srcPath = ( $src instanceof FSFile ) ? $src->getPath() : $src; $srcPath = ( $src instanceof FSFile ) ? $src->getPath() : $src;
if ( !$props ) { if ( !$props ) {
if ( $this->repo->isVirtualUrl( $srcPath ) if ( $this->repo->isVirtualUrl( $srcPath )
|| FileBackend::isStoragePath( $srcPath ) || FileBackend::isStoragePath( $srcPath )
) { ) {
$props = $this->repo->getFileProps( $srcPath ); $props = $this->repo->getFileProps( $srcPath );
} else { } else {
$mwProps = new MWFileProps( MediaWiki\MediaWikiSe rvices::getInstance()->getMimeAnalyzer() ); $mwProps = new MWFileProps( MediaWikiServices::ge tInstance()->getMimeAnalyzer() );
$props = $mwProps->getPropsFromPath( $srcPath, tr ue ); $props = $mwProps->getPropsFromPath( $srcPath, tr ue );
} }
} }
$options = []; $options = [];
$handler = MediaHandler::getHandler( $props['mime'] ); $handler = MediaHandler::getHandler( $props['mime'] );
if ( $handler ) { if ( $handler ) {
$metadata = Wikimedia\quietCall( 'unserialize', $props['m etadata'] ); $metadata = Wikimedia\quietCall( 'unserialize', $props['m etadata'] );
if ( !is_array( $metadata ) ) { if ( !is_array( $metadata ) ) {
skipping to change at line 1364 skipping to change at line 1368
// Once the second operation goes through, then the curre nt version was // Once the second operation goes through, then the curre nt version was
// updated and we must therefore update the DB too. // updated and we must therefore update the DB too.
$oldver = $status->value; $oldver = $status->value;
$uploadStatus = $this->recordUpload2( $uploadStatus = $this->recordUpload2(
$oldver, $oldver,
$comment, $comment,
$pageText, $pageText,
$props, $props,
$timestamp, $timestamp,
$user, $user,
$tags $tags,
$createNullRevision
); );
if ( !$uploadStatus->isOK() ) { if ( !$uploadStatus->isOK() ) {
if ( $uploadStatus->hasMessage( 'filenotfound' ) ) { if ( $uploadStatus->hasMessage( 'filenotfound' ) ) {
// update filenotfound error with more sp ecific path // update filenotfound error with more sp ecific path
$status->fatal( 'filenotfound', $srcPath ); $status->fatal( 'filenotfound', $srcPath );
} else { } else {
$status->merge( $uploadStatus ); $status->merge( $uploadStatus );
} }
} }
} }
skipping to change at line 1422 skipping to change at line 1427
/** /**
* Record a file upload in the upload log and the image table * Record a file upload in the upload log and the image table
* @param string $oldver * @param string $oldver
* @param string $comment * @param string $comment
* @param string $pageText * @param string $pageText
* @param bool|array $props * @param bool|array $props
* @param string|bool $timestamp * @param string|bool $timestamp
* @param null|User $user * @param null|User $user
* @param string[] $tags * @param string[] $tags
* @param bool $createNullRevision Set to false to avoid creation of a nu
ll revision on file
* upload, see T193621
* @return Status * @return Status
*/ */
function recordUpload2( function recordUpload2(
$oldver, $comment, $pageText, $props = false, $timestamp = false, $oldver, $comment, $pageText, $props = false, $timestamp = false,
$user = null, $tags = [] $user = null, $tags = [],
$createNullRevision = true
) { ) {
global $wgCommentTableSchemaMigrationStage, $wgActorTableSchemaMi grationStage; global $wgCommentTableSchemaMigrationStage, $wgActorTableSchemaMi grationStage;
if ( is_null( $user ) ) { if ( is_null( $user ) ) {
global $wgUser; global $wgUser;
$user = $wgUser; $user = $wgUser;
} }
$dbw = $this->repo->getMasterDB(); $dbw = $this->repo->getMasterDB();
skipping to change at line 1465 skipping to change at line 1473
wfDebug( __METHOD__ . ": File " . $this->getRel() . " wen t missing!\n" ); wfDebug( __METHOD__ . ": File " . $this->getRel() . " wen t missing!\n" );
return Status::newFatal( 'filenotfound', $this->getRel() ); return Status::newFatal( 'filenotfound', $this->getRel() );
} }
$dbw->startAtomic( __METHOD__ ); $dbw->startAtomic( __METHOD__ );
# Test to see if the row exists using INSERT IGNORE # Test to see if the row exists using INSERT IGNORE
# This avoids race conditions by locking the row until the commit , and also # This avoids race conditions by locking the row until the commit , and also
# doesn't deadlock. SELECT FOR UPDATE causes a deadlock for every race condition. # doesn't deadlock. SELECT FOR UPDATE causes a deadlock for every race condition.
$commentStore = CommentStore::getStore(); $commentStore = MediaWikiServices::getInstance()->getCommentStore
list( $commentFields, $commentCallback ) = ();
$commentStore->insertWithTempTable( $dbw, 'img_descriptio $commentFields = $commentStore->insert( $dbw, 'img_description',
n', $comment ); $comment );
$actorMigration = ActorMigration::newMigration(); $actorMigration = ActorMigration::newMigration();
$actorFields = $actorMigration->getInsertValues( $dbw, 'img_user' , $user ); $actorFields = $actorMigration->getInsertValues( $dbw, 'img_user' , $user );
$dbw->insert( 'image', $dbw->insert( 'image',
[ [
'img_name' => $this->getName(), 'img_name' => $this->getName(),
'img_size' => $this->size, 'img_size' => $this->size,
'img_width' => intval( $this->width ), 'img_width' => intval( $this->width ),
'img_height' => intval( $this->height ), 'img_height' => intval( $this->height ),
'img_bits' => $this->bits, 'img_bits' => $this->bits,
'img_media_type' => $this->media_type, 'img_media_type' => $this->media_type,
skipping to change at line 1538 skipping to change at line 1545
'oi_major_mime' => 'img_major_mime', 'oi_major_mime' => 'img_major_mime',
'oi_minor_mime' => 'img_minor_mime', 'oi_minor_mime' => 'img_minor_mime',
'oi_sha1' => 'img_sha1', 'oi_sha1' => 'img_sha1',
]; ];
$joins = []; $joins = [];
if ( $wgCommentTableSchemaMigrationStage <= MIGRATION_WRI TE_BOTH ) { if ( $wgCommentTableSchemaMigrationStage <= MIGRATION_WRI TE_BOTH ) {
$fields['oi_description'] = 'img_description'; $fields['oi_description'] = 'img_description';
} }
if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRI TE_BOTH ) { if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRI TE_BOTH ) {
$tables[] = 'image_comment_temp'; $fields['oi_description_id'] = 'img_description_i
$fields['oi_description_id'] = 'imgcomment_descri d';
ption_id';
$joins['image_comment_temp'] = [
$wgCommentTableSchemaMigrationStage === M
IGRATION_NEW ? 'JOIN' : 'LEFT JOIN',
[ 'imgcomment_name = img_name' ]
];
} }
if ( $wgCommentTableSchemaMigrationStage !== MIGRATION_OL D && if ( $wgCommentTableSchemaMigrationStage !== MIGRATION_OL D &&
$wgCommentTableSchemaMigrationStage !== MIGRATION _NEW $wgCommentTableSchemaMigrationStage !== MIGRATION _NEW
) { ) {
// Upgrade any rows that are still old-style. Oth erwise an upgrade // Upgrade any rows that are still old-style. Oth erwise an upgrade
// might be missed if a deletion happens while th e migration script // might be missed if a deletion happens while th e migration script
// is running. // is running.
$res = $dbw->select( $res = $dbw->select(
[ 'image', 'image_comment_temp' ], [ 'image' ],
[ 'img_name', 'img_description' ], [ 'img_name', 'img_description' ],
[ 'img_name' => $this->getName(), 'imgcom [
ment_name' => null ], 'img_name' => $this->getName(),
__METHOD__, 'img_description_id' => 0,
[], ],
[ 'image_comment_temp' => [ 'LEFT JOIN', __METHOD__
[ 'imgcomment_name = img_name' ] ] ]
); );
foreach ( $res as $row ) { foreach ( $res as $row ) {
list( , $callback ) = $commentStore->inse $imgFields = $commentStore->insert( $dbw,
rtWithTempTable( 'img_description', $row->img_description );
$dbw, 'img_description', $row->im $dbw->update(
g_description 'image',
$imgFields,
[ 'img_name' => $row->img_name ],
__METHOD__
); );
$callback( $row->img_name );
} }
} }
if ( $wgActorTableSchemaMigrationStage <= MIGRATION_WRITE _BOTH ) { if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WR ITE_OLD ) {
$fields['oi_user'] = 'img_user'; $fields['oi_user'] = 'img_user';
$fields['oi_user_text'] = 'img_user_text'; $fields['oi_user_text'] = 'img_user_text';
} }
if ( $wgActorTableSchemaMigrationStage >= MIGRATION_WRITE _BOTH ) { if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WR ITE_NEW ) {
$fields['oi_actor'] = 'img_actor'; $fields['oi_actor'] = 'img_actor';
} }
if ( $wgActorTableSchemaMigrationStage !== MIGRATION_OLD if (
&& ( $wgActorTableSchemaMigrationStage & SCHEMA_COMP
$wgActorTableSchemaMigrationStage !== MIGRATION_N AT_WRITE_BOTH ) === SCHEMA_COMPAT_WRITE_BOTH
EW
) { ) {
// Upgrade any rows that are still old-style. Oth erwise an upgrade // Upgrade any rows that are still old-style. Oth erwise an upgrade
// might be missed if a deletion happens while th e migration script // might be missed if a deletion happens while th e migration script
// is running. // is running.
$res = $dbw->select( $res = $dbw->select(
[ 'image' ], [ 'image' ],
[ 'img_name', 'img_user', 'img_user_text' ], [ 'img_name', 'img_user', 'img_user_text' ],
[ 'img_name' => $this->getName(), 'img_ac tor' => 0 ], [ 'img_name' => $this->getName(), 'img_ac tor' => 0 ],
__METHOD__ __METHOD__
); );
skipping to change at line 1625 skipping to change at line 1631
'img_media_type' => $this->media_type, 'img_media_type' => $this->media_type,
'img_major_mime' => $this->major_mime, 'img_major_mime' => $this->major_mime,
'img_minor_mime' => $this->minor_mime, 'img_minor_mime' => $this->minor_mime,
'img_timestamp' => $timestamp, 'img_timestamp' => $timestamp,
'img_metadata' => $dbw->encodeBlob( $this ->metadata ), 'img_metadata' => $dbw->encodeBlob( $this ->metadata ),
'img_sha1' => $this->sha1 'img_sha1' => $this->sha1
] + $commentFields + $actorFields, ] + $commentFields + $actorFields,
[ 'img_name' => $this->getName() ], [ 'img_name' => $this->getName() ],
__METHOD__ __METHOD__
); );
if ( $wgCommentTableSchemaMigrationStage > MIGRATION_OLD
) {
// So $commentCallback can insert the new row
$dbw->delete( 'image_comment_temp', [ 'imgcomment
_name' => $this->getName() ], __METHOD__ );
}
} }
$commentCallback( $this->getName() );
$descTitle = $this->getTitle(); $descTitle = $this->getTitle();
$descId = $descTitle->getArticleID(); $descId = $descTitle->getArticleID();
$wikiPage = new WikiFilePage( $descTitle ); $wikiPage = new WikiFilePage( $descTitle );
$wikiPage->setFile( $this ); $wikiPage->setFile( $this );
// Add the log entry... // Add the log entry...
$logEntry = new ManualLogEntry( 'upload', $reupload ? 'overwrite' : 'upload' ); $logEntry = new ManualLogEntry( 'upload', $reupload ? 'overwrite' : 'upload' );
$logEntry->setTimestamp( $this->timestamp ); $logEntry->setTimestamp( $this->timestamp );
$logEntry->setPerformer( $user ); $logEntry->setPerformer( $user );
skipping to change at line 1665 skipping to change at line 1666
// For a similar reason, we avoid making an RC entry // For a similar reason, we avoid making an RC entry
// now and wait until the page exists. // now and wait until the page exists.
$logId = $logEntry->insert(); $logId = $logEntry->insert();
if ( $descTitle->exists() ) { if ( $descTitle->exists() ) {
// Use own context to get the action text in content lang uage // Use own context to get the action text in content lang uage
$formatter = LogFormatter::newFromEntry( $logEntry ); $formatter = LogFormatter::newFromEntry( $logEntry );
$formatter->setContext( RequestContext::newExtraneousCont ext( $descTitle ) ); $formatter->setContext( RequestContext::newExtraneousCont ext( $descTitle ) );
$editSummary = $formatter->getPlainActionText(); $editSummary = $formatter->getPlainActionText();
$nullRevision = Revision::newNullRevision( $nullRevision = $createNullRevision === false ? null : Re vision::newNullRevision(
$dbw, $dbw,
$descId, $descId,
$editSummary, $editSummary,
false, false,
$user $user
); );
if ( $nullRevision ) { if ( $nullRevision ) {
$nullRevision->insertOn( $dbw ); $nullRevision->insertOn( $dbw );
Hooks::run( Hooks::run(
'NewRevisionFromEditComplete', 'NewRevisionFromEditComplete',
skipping to change at line 1692 skipping to change at line 1693
$newPageContent = null; $newPageContent = null;
} else { } else {
// Make the description page and RC log entry post-commit // Make the description page and RC log entry post-commit
$newPageContent = ContentHandler::makeContent( $pageText, $descTitle ); $newPageContent = ContentHandler::makeContent( $pageText, $descTitle );
} }
# Defer purges, page creation, and link updates in case they erro r out. # Defer purges, page creation, and link updates in case they erro r out.
# The most important thing is that files and the DB registry stay synced. # The most important thing is that files and the DB registry stay synced.
$dbw->endAtomic( __METHOD__ ); $dbw->endAtomic( __METHOD__ );
$fname = __METHOD__;
# Do some cache purges after final commit so that: # Do some cache purges after final commit so that:
# a) Changes are more likely to be seen post-purge # a) Changes are more likely to be seen post-purge
# b) They won't cause rollback of the log publish/update above # b) They won't cause rollback of the log publish/update above
DeferredUpdates::addUpdate( DeferredUpdates::addUpdate(
new AutoCommitUpdate( new AutoCommitUpdate(
$dbw, $dbw,
__METHOD__, __METHOD__,
function () use ( function () use (
$reupload, $wikiPage, $newPageContent, $c omment, $user, $reupload, $wikiPage, $newPageContent, $c omment, $user,
$logEntry, $logId, $descId, $tags $logEntry, $logId, $descId, $tags, $fname
) { ) {
# Update memcache after the commit # Update memcache after the commit
$this->invalidateCache(); $this->invalidateCache();
$updateLogPage = false; $updateLogPage = false;
if ( $newPageContent ) { if ( $newPageContent ) {
# New file page; create the descr iption page. # New file page; create the descr iption page.
# There's already a log entry, so don't make a second RC entry # There's already a log entry, so don't make a second RC entry
# CDN and file cache for the desc ription page are purged by doEditContent. # CDN and file cache for the desc ription page are purged by doEditContent.
$status = $wikiPage->doEditConten t( $status = $wikiPage->doEditConten t(
skipping to change at line 1754 skipping to change at line 1756
$logParams['associated_rev_id'] = $logEnt ry->getAssociatedRevId(); $logParams['associated_rev_id'] = $logEnt ry->getAssociatedRevId();
$update = [ 'log_params' => LogEntryBase: :makeParamBlob( $logParams ) ]; $update = [ 'log_params' => LogEntryBase: :makeParamBlob( $logParams ) ];
if ( $updateLogPage ) { if ( $updateLogPage ) {
# Also log page, in case where we just created it above # Also log page, in case where we just created it above
$update['log_page'] = $updateLogP age; $update['log_page'] = $updateLogP age;
} }
$this->getRepo()->getMasterDB()->update( $this->getRepo()->getMasterDB()->update(
'logging', 'logging',
$update, $update,
[ 'log_id' => $logId ], [ 'log_id' => $logId ],
__METHOD__ $fname
); );
$this->getRepo()->getMasterDB()->insert( $this->getRepo()->getMasterDB()->insert(
'log_search', 'log_search',
[ [
'ls_field' => 'associated _rev_id', 'ls_field' => 'associated _rev_id',
'ls_value' => $logEntry-> getAssociatedRevId(), 'ls_value' => $logEntry-> getAssociatedRevId(),
'ls_log_id' => $logId, 'ls_log_id' => $logId,
], ],
__METHOD__ $fname
); );
# Add change tags, if any # Add change tags, if any
if ( $tags ) { if ( $tags ) {
$logEntry->setTags( $tags ); $logEntry->setTags( $tags );
} }
# Uploads can be patrolled # Uploads can be patrolled
$logEntry->setIsPatrollable( true ); $logEntry->setIsPatrollable( true );
skipping to change at line 2111 skipping to change at line 2113
} }
/** /**
* Get the HTML text of the description page * Get the HTML text of the description page
* This is not used by ImagePage for local files, since (among other thin gs) * This is not used by ImagePage for local files, since (among other thin gs)
* it skips the parser cache. * it skips the parser cache.
* *
* @param Language|null $lang What language to get description in (Option al) * @param Language|null $lang What language to get description in (Option al)
* @return string|false * @return string|false
*/ */
function getDescriptionText( $lang = null ) { function getDescriptionText( Language $lang = null ) {
$revision = Revision::newFromTitle( $this->title, false, Revision $store = MediaWikiServices::getInstance()->getRevisionStore();
::READ_NORMAL ); $revision = $store->getRevisionByTitle( $this->title, 0, Revision
::READ_NORMAL );
if ( !$revision ) { if ( !$revision ) {
return false; return false;
} }
$content = $revision->getContent();
if ( !$content ) { $renderer = MediaWikiServices::getInstance()->getRevisionRenderer
();
$rendered = $renderer->getRenderedRevision( $revision, new Parser
Options( null, $lang ) );
if ( !$rendered ) {
// audience check failed
return false; return false;
} }
$pout = $content->getParserOutput( $this->title, null, new Parser Options( null, $lang ) );
$pout = $rendered->getRevisionParserOutput();
return $pout->getText(); return $pout->getText();
} }
/** /**
* @param int $audience * @param int $audience
* @param User|null $user * @param User|null $user
* @return string * @return string
*/ */
function getDescription( $audience = self::FOR_PUBLIC, User $user = null ) { function getDescription( $audience = self::FOR_PUBLIC, User $user = null ) {
$this->load(); $this->load();
skipping to change at line 2204 skipping to change at line 2211
} }
/** /**
* @return bool Whether to cache in RepoGroup (this avoids OOMs) * @return bool Whether to cache in RepoGroup (this avoids OOMs)
*/ */
function isCacheable() { function isCacheable() {
$this->load(); $this->load();
// If extra data (metadata) was not loaded then it must have been large // If extra data (metadata) was not loaded then it must have been large
return $this->extraDataLoaded return $this->extraDataLoaded
&& strlen( serialize( $this->metadata ) ) <= self::CACHE_FIELD_MA X_LEN; && strlen( serialize( $this->metadata ) ) <= self::CACHE_ FIELD_MAX_LEN;
} }
/** /**
* @return Status * @return Status
* @since 1.28 * @since 1.28
*/ */
public function acquireFileLock() { public function acquireFileLock() {
return $this->getRepo()->getBackend()->lockFiles( return Status::wrap( $this->getRepo()->getBackend()->lockFiles(
[ $this->getPath() ], LockManager::LOCK_EX, 10 [ $this->getPath() ], LockManager::LOCK_EX, 10
); ) );
} }
/** /**
* @return Status * @return Status
* @since 1.28 * @since 1.28
*/ */
public function releaseFileLock() { public function releaseFileLock() {
return $this->getRepo()->getBackend()->unlockFiles( return Status::wrap( $this->getRepo()->getBackend()->unlockFiles(
[ $this->getPath() ], LockManager::LOCK_EX [ $this->getPath() ], LockManager::LOCK_EX
); ) );
} }
/** /**
* Start an atomic DB section and lock the image for update * Start an atomic DB section and lock the image for update
* or increments a reference counter if the lock is already held * or increments a reference counter if the lock is already held
* *
* This method should not be used outside of LocalFile/LocalFile*Batch * This method should not be used outside of LocalFile/LocalFile*Batch
* *
* @throws LocalFileLockError Throws an error if the lock was not acquire d * @throws LocalFileLockError Throws an error if the lock was not acquire d
* @return bool Whether the file lock owns/spawned the DB transaction * @return bool Whether the file lock owns/spawned the DB transaction
skipping to change at line 2473 skipping to change at line 2480
return $hashes; return $hashes;
} }
protected function doDBInserts() { protected function doDBInserts() {
global $wgCommentTableSchemaMigrationStage, $wgActorTableSchemaMi grationStage; global $wgCommentTableSchemaMigrationStage, $wgActorTableSchemaMi grationStage;
$now = time(); $now = time();
$dbw = $this->file->repo->getMasterDB(); $dbw = $this->file->repo->getMasterDB();
$commentStore = CommentStore::getStore(); $commentStore = MediaWikiServices::getInstance()->getCommentStore ();
$actorMigration = ActorMigration::newMigration(); $actorMigration = ActorMigration::newMigration();
$encTimestamp = $dbw->addQuotes( $dbw->timestamp( $now ) ); $encTimestamp = $dbw->addQuotes( $dbw->timestamp( $now ) );
$encUserId = $dbw->addQuotes( $this->user->getId() ); $encUserId = $dbw->addQuotes( $this->user->getId() );
$encGroup = $dbw->addQuotes( 'deleted' ); $encGroup = $dbw->addQuotes( 'deleted' );
$ext = $this->file->getExtension(); $ext = $this->file->getExtension();
$dotExt = $ext === '' ? '' : ".$ext"; $dotExt = $ext === '' ? '' : ".$ext";
$encExt = $dbw->addQuotes( $dotExt ); $encExt = $dbw->addQuotes( $dotExt );
list( $oldRels, $deleteCurrent ) = $this->getOldRels(); list( $oldRels, $deleteCurrent ) = $this->getOldRels();
skipping to change at line 2527 skipping to change at line 2534
$fields += array_map( $fields += array_map(
[ $dbw, 'addQuotes' ], [ $dbw, 'addQuotes' ],
$commentStore->insert( $dbw, 'fa_deleted_reason', $this->reason ) $commentStore->insert( $dbw, 'fa_deleted_reason', $this->reason )
); );
if ( $wgCommentTableSchemaMigrationStage <= MIGRATION_WRI TE_BOTH ) { if ( $wgCommentTableSchemaMigrationStage <= MIGRATION_WRI TE_BOTH ) {
$fields['fa_description'] = 'img_description'; $fields['fa_description'] = 'img_description';
} }
if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRI TE_BOTH ) { if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRI TE_BOTH ) {
$tables[] = 'image_comment_temp'; $fields['fa_description_id'] = 'img_description_i
$fields['fa_description_id'] = 'imgcomment_descri d';
ption_id';
$joins['image_comment_temp'] = [
$wgCommentTableSchemaMigrationStage === M
IGRATION_NEW ? 'JOIN' : 'LEFT JOIN',
[ 'imgcomment_name = img_name' ]
];
} }
if ( $wgCommentTableSchemaMigrationStage !== MIGRATION_OL D && if ( $wgCommentTableSchemaMigrationStage !== MIGRATION_OL D &&
$wgCommentTableSchemaMigrationStage !== MIGRATION _NEW $wgCommentTableSchemaMigrationStage !== MIGRATION _NEW
) { ) {
// Upgrade any rows that are still old-style. Oth erwise an upgrade // Upgrade any rows that are still old-style. Oth erwise an upgrade
// might be missed if a deletion happens while th e migration script // might be missed if a deletion happens while th e migration script
// is running. // is running.
$res = $dbw->select( $res = $dbw->select(
[ 'image', 'image_comment_temp' ], [ 'image' ],
[ 'img_name', 'img_description' ], [ 'img_name', 'img_description' ],
[ 'img_name' => $this->file->getName(), ' [
imgcomment_name' => null ], 'img_name' => $this->file->getNam
__METHOD__, e(),
[], 'img_description_id' => 0,
[ 'image_comment_temp' => [ 'LEFT JOIN', ],
[ 'imgcomment_name = img_name' ] ] ] __METHOD__
); );
foreach ( $res as $row ) { foreach ( $res as $row ) {
list( , $callback ) = $commentStore->inse $imgFields = $commentStore->insert( $dbw,
rtWithTempTable( 'img_description', $row->img_description );
$dbw, 'img_description', $row->im $dbw->update(
g_description 'image',
$imgFields,
[ 'img_name' => $row->img_name ],
__METHOD__
); );
$callback( $row->img_name );
} }
} }
if ( $wgActorTableSchemaMigrationStage <= MIGRATION_WRITE _BOTH ) { if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WR ITE_OLD ) {
$fields['fa_user'] = 'img_user'; $fields['fa_user'] = 'img_user';
$fields['fa_user_text'] = 'img_user_text'; $fields['fa_user_text'] = 'img_user_text';
} }
if ( $wgActorTableSchemaMigrationStage >= MIGRATION_WRITE _BOTH ) { if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WR ITE_NEW ) {
$fields['fa_actor'] = 'img_actor'; $fields['fa_actor'] = 'img_actor';
} }
if ( $wgActorTableSchemaMigrationStage !== MIGRATION_OLD if (
&& ( $wgActorTableSchemaMigrationStage & SCHEMA_COMP
$wgActorTableSchemaMigrationStage !== MIGRATION_N AT_WRITE_BOTH ) === SCHEMA_COMPAT_WRITE_BOTH
EW
) { ) {
// Upgrade any rows that are still old-style. Oth erwise an upgrade // Upgrade any rows that are still old-style. Oth erwise an upgrade
// might be missed if a deletion happens while th e migration script // might be missed if a deletion happens while th e migration script
// is running. // is running.
$res = $dbw->select( $res = $dbw->select(
[ 'image' ], [ 'image' ],
[ 'img_name', 'img_user', 'img_user_text' ], [ 'img_name', 'img_user', 'img_user_text' ],
[ 'img_name' => $this->file->getName(), ' img_actor' => 0 ], [ 'img_name' => $this->file->getName(), ' img_actor' => 0 ],
__METHOD__ __METHOD__
); );
skipping to change at line 2644 skipping to change at line 2650
+ $commentStore->insert( $dbw, 'fa_descri ption', $comment ) + $commentStore->insert( $dbw, 'fa_descri ption', $comment )
+ $actorMigration->getInsertValues( $dbw, 'fa_user', $user ); + $actorMigration->getInsertValues( $dbw, 'fa_user', $user );
} }
} }
$dbw->insert( 'filearchive', $rowsInsert, __METHOD__ ); $dbw->insert( 'filearchive', $rowsInsert, __METHOD__ );
} }
} }
function doDBDeletes() { function doDBDeletes() {
global $wgCommentTableSchemaMigrationStage;
$dbw = $this->file->repo->getMasterDB(); $dbw = $this->file->repo->getMasterDB();
list( $oldRels, $deleteCurrent ) = $this->getOldRels(); list( $oldRels, $deleteCurrent ) = $this->getOldRels();
if ( count( $oldRels ) ) { if ( count( $oldRels ) ) {
$dbw->delete( 'oldimage', $dbw->delete( 'oldimage',
[ [
'oi_name' => $this->file->getName(), 'oi_name' => $this->file->getName(),
'oi_archive_name' => array_keys( $oldRels ) 'oi_archive_name' => array_keys( $oldRels )
], __METHOD__ ); ], __METHOD__ );
} }
if ( $deleteCurrent ) { if ( $deleteCurrent ) {
$dbw->delete( 'image', [ 'img_name' => $this->file->getNa me() ], __METHOD__ ); $dbw->delete( 'image', [ 'img_name' => $this->file->getNa me() ], __METHOD__ );
if ( $wgCommentTableSchemaMigrationStage > MIGRATION_OLD
) {
$dbw->delete(
'image_comment_temp', [ 'imgcomment_name'
=> $this->file->getName() ], __METHOD__
);
}
} }
} }
/** /**
* Run the transaction * Run the transaction
* @return Status * @return Status
*/ */
public function execute() { public function execute() {
$repo = $this->file->getRepo(); $repo = $this->file->getRepo();
$this->file->lock(); $this->file->lock();
skipping to change at line 2833 skipping to change at line 2832
$repo = $this->file->getRepo(); $repo = $this->file->getRepo();
if ( !$this->all && !$this->ids ) { if ( !$this->all && !$this->ids ) {
// Do nothing // Do nothing
return $repo->newGood(); return $repo->newGood();
} }
$lockOwnsTrx = $this->file->lock(); $lockOwnsTrx = $this->file->lock();
$dbw = $this->file->repo->getMasterDB(); $dbw = $this->file->repo->getMasterDB();
$commentStore = CommentStore::getStore(); $commentStore = MediaWikiServices::getInstance()->getCommentStore ();
$actorMigration = ActorMigration::newMigration(); $actorMigration = ActorMigration::newMigration();
$status = $this->file->repo->newGood(); $status = $this->file->repo->newGood();
$exists = (bool)$dbw->selectField( 'image', '1', $exists = (bool)$dbw->selectField( 'image', '1',
[ 'img_name' => $this->file->getName() ], [ 'img_name' => $this->file->getName() ],
__METHOD__, __METHOD__,
// The lock() should already prevents changes, but this s till may need // The lock() should already prevents changes, but this s till may need
// to bypass any transaction snapshot. However, if lock() started the // to bypass any transaction snapshot. However, if lock() started the
// trx (which it probably did) then snapshot is post-lock and up-to-date. // trx (which it probably did) then snapshot is post-lock and up-to-date.
skipping to change at line 2927 skipping to change at line 2926
'media_type' => $row->fa_media_type, 'media_type' => $row->fa_media_type,
'metadata' => $row->fa_metadata 'metadata' => $row->fa_metadata
]; ];
} }
$comment = $commentStore->getComment( 'fa_description', $ row ); $comment = $commentStore->getComment( 'fa_description', $ row );
$user = User::newFromAnyId( $row->fa_user, $row->fa_user_ text, $row->fa_actor ); $user = User::newFromAnyId( $row->fa_user, $row->fa_user_ text, $row->fa_actor );
if ( $first && !$exists ) { if ( $first && !$exists ) {
// This revision will be published as the new cur rent version // This revision will be published as the new cur rent version
$destRel = $this->file->getRel(); $destRel = $this->file->getRel();
list( $commentFields, $commentCallback ) = $commentFields = $commentStore->insert( $dbw, 'im
$commentStore->insertWithTempTable( $dbw, g_description', $comment );
'img_description', $comment );
$actorFields = $actorMigration->getInsertValues( $dbw, 'img_user', $user ); $actorFields = $actorMigration->getInsertValues( $dbw, 'img_user', $user );
$insertCurrent = [ $insertCurrent = [
'img_name' => $row->fa_name, 'img_name' => $row->fa_name,
'img_size' => $row->fa_size, 'img_size' => $row->fa_size,
'img_width' => $row->fa_width, 'img_width' => $row->fa_width,
'img_height' => $row->fa_height, 'img_height' => $row->fa_height,
'img_metadata' => $props['metadata'], 'img_metadata' => $props['metadata'],
'img_bits' => $row->fa_bits, 'img_bits' => $row->fa_bits,
'img_media_type' => $props['media_type'], 'img_media_type' => $props['media_type'],
'img_major_mime' => $props['major_mime'], 'img_major_mime' => $props['major_mime'],
skipping to change at line 3040 skipping to change at line 3038
} }
// Run the DB updates // Run the DB updates
// Because we have locked the image row, key conflicts should be rare. // Because we have locked the image row, key conflicts should be rare.
// If they do occur, we can roll back the transaction at this tim e with // If they do occur, we can roll back the transaction at this tim e with
// no data loss, but leaving unregistered files scattered through out the // no data loss, but leaving unregistered files scattered through out the
// public zone. // public zone.
// This is not ideal, which is why it's important to lock the ima ge row. // This is not ideal, which is why it's important to lock the ima ge row.
if ( $insertCurrent ) { if ( $insertCurrent ) {
$dbw->insert( 'image', $insertCurrent, __METHOD__ ); $dbw->insert( 'image', $insertCurrent, __METHOD__ );
$commentCallback( $insertCurrent['img_name'] );
} }
if ( $insertBatch ) { if ( $insertBatch ) {
$dbw->insert( 'oldimage', $insertBatch, __METHOD__ ); $dbw->insert( 'oldimage', $insertBatch, __METHOD__ );
} }
if ( $deleteIds ) { if ( $deleteIds ) {
$dbw->delete( 'filearchive', $dbw->delete( 'filearchive',
[ 'fa_id' => $deleteIds ], [ 'fa_id' => $deleteIds ],
__METHOD__ ); __METHOD__ );
skipping to change at line 3142 skipping to change at line 3139
$this->cleanupBatch = $this->removeNonexistentFromCleanup( $this- >cleanupBatch ); $this->cleanupBatch = $this->removeNonexistentFromCleanup( $this- >cleanupBatch );
$status = $this->file->repo->cleanupDeletedBatch( $this->cleanupB atch ); $status = $this->file->repo->cleanupDeletedBatch( $this->cleanupB atch );
return $status; return $status;
} }
/** /**
* Cleanup a failed batch. The batch was only partially successful, so * Cleanup a failed batch. The batch was only partially successful, so
* rollback by removing all items that were succesfully copied. * rollback by removing all items that were successfully copied.
* *
* @param Status $storeStatus * @param Status $storeStatus
* @param array[] $storeBatch * @param array[] $storeBatch
*/ */
protected function cleanupFailedBatch( $storeStatus, $storeBatch ) { protected function cleanupFailedBatch( $storeStatus, $storeBatch ) {
$cleanupBatch = []; $cleanupBatch = [];
foreach ( $storeStatus->success as $i => $success ) { foreach ( $storeStatus->success as $i => $success ) {
// Check if this item of the batch was successfully copie d // Check if this item of the batch was successfully copie d
if ( $success ) { if ( $success ) {
skipping to change at line 3340 skipping to change at line 3337
* Verify the database updates and return a new Status indicating how * Verify the database updates and return a new Status indicating how
* many rows would be updated. * many rows would be updated.
* *
* @return Status * @return Status
*/ */
protected function verifyDBUpdates() { protected function verifyDBUpdates() {
$repo = $this->file->repo; $repo = $this->file->repo;
$status = $repo->newGood(); $status = $repo->newGood();
$dbw = $this->db; $dbw = $this->db;
$hasCurrent = $dbw->selectField( $hasCurrent = $dbw->lockForUpdate(
'image', 'image',
'1',
[ 'img_name' => $this->oldName ], [ 'img_name' => $this->oldName ],
__METHOD__, __METHOD__
[ 'FOR UPDATE' ]
); );
$oldRowCount = $dbw->selectRowCount( $oldRowCount = $dbw->lockForUpdate(
'oldimage', 'oldimage',
'*',
[ 'oi_name' => $this->oldName ], [ 'oi_name' => $this->oldName ],
__METHOD__, __METHOD__
[ 'FOR UPDATE' ]
); );
if ( $hasCurrent ) { if ( $hasCurrent ) {
$status->successCount++; $status->successCount++;
} else { } else {
$status->failCount++; $status->failCount++;
} }
$status->successCount += $oldRowCount; $status->successCount += $oldRowCount;
// T36934: oldCount is based on files that actually exist. // T36934: oldCount is based on files that actually exist.
// There may be more DB rows than such files, in which case $affe cted // There may be more DB rows than such files, in which case $affe cted
skipping to change at line 3377 skipping to change at line 3370
} }
return $status; return $status;
} }
/** /**
* Do the database updates and return a new Status indicating how * Do the database updates and return a new Status indicating how
* many rows where updated. * many rows where updated.
*/ */
protected function doDBUpdates() { protected function doDBUpdates() {
global $wgCommentTableSchemaMigrationStage;
$dbw = $this->db; $dbw = $this->db;
// Update current image // Update current image
$dbw->update( $dbw->update(
'image', 'image',
[ 'img_name' => $this->newName ], [ 'img_name' => $this->newName ],
[ 'img_name' => $this->oldName ], [ 'img_name' => $this->oldName ],
__METHOD__ __METHOD__
); );
if ( $wgCommentTableSchemaMigrationStage > MIGRATION_OLD ) {
$dbw->update(
'image_comment_temp',
[ 'imgcomment_name' => $this->newName ],
[ 'imgcomment_name' => $this->oldName ],
__METHOD__
);
}
// Update old images // Update old images
$dbw->update( $dbw->update(
'oldimage', 'oldimage',
[ [
'oi_name' => $this->newName, 'oi_name' => $this->newName,
'oi_archive_name = ' . $dbw->strreplace( 'oi_arch ive_name', 'oi_archive_name = ' . $dbw->strreplace( 'oi_arch ive_name',
$dbw->addQuotes( $this->oldName ), $dbw-> addQuotes( $this->newName ) ), $dbw->addQuotes( $this->oldName ), $dbw-> addQuotes( $this->newName ) ),
], ],
[ 'oi_name' => $this->oldName ], [ 'oi_name' => $this->oldName ],
 End of changes. 66 change blocks. 
136 lines changed or deleted 109 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)