56 'table' =>
'revision_actor_temp',
57 'pk' =>
'revactor_rev',
58 'field' =>
'revactor_actor',
61 'revactor_timestamp' =>
'rev_timestamp',
62 'revactor_page' =>
'rev_page',
102 'ipb_by' => [
'ipb_by_text',
'ipb_by_actor' ],
114 throw new InvalidArgumentException(
'$stage must include a write mode' );
117 throw new InvalidArgumentException(
'$stage must include a read mode' );
120 throw new InvalidArgumentException(
'Cannot read both schemas' );
123 throw new InvalidArgumentException(
'Cannot read the old schema without also writing it' );
126 throw new InvalidArgumentException(
'Cannot read the new schema without also writing it' );
137 return MediaWikiServices::getInstance()->getActorMigration();
145 if ( isset( self::$removed[$key] ) ) {
146 throw new InvalidArgumentException(
147 "Use of " . static::class .
" for '$key' was removed in MediaWiki " . self::$removed[$key]
150 if ( !empty( self::$deprecated[$key] ) ) {
151 wfDeprecated( static::class .
" for '$key'", self::$deprecated[$key],
false, 3 );
179 return self::$specialFields[$key] ?? [ $key .
'_text', substr( $key, 0, -5 ) .
'_actor' ];
195 self::checkDeprecation( $key );
197 if ( !isset( $this->joinCache[$key] ) ) {
202 list( $text, $actor ) = self::getFieldNames( $key );
205 $fields[$key] = $key;
206 $fields[$text] = $text;
207 $fields[$actor] =
'NULL';
209 if ( isset( self::$tempTables[$key] ) ) {
210 $t = self::$tempTables[$key];
211 $alias =
"temp_$key";
212 $tables[$alias] =
$t[
'table'];
213 $joins[$alias] = [
'JOIN',
"{$alias}.{$t['pk']} = {$t['joinPK']}" ];
214 $joinField =
"{$alias}.{$t['field']}";
219 $alias =
"actor_$key";
220 $tables[$alias] =
'actor';
221 $joins[$alias] = [
'JOIN',
"{$alias}.actor_id = {$joinField}" ];
223 $fields[$key] =
"{$alias}.actor_user";
224 $fields[$text] =
"{$alias}.actor_name";
225 $fields[$actor] = $joinField;
228 $this->joinCache[$key] = [
235 return $this->joinCache[$key];
251 [
'actor_name' => $user->
getName() ],
254 if ( $row ===
false ) {
258 return (
int)$row->actor_id;
274 'actor_user' => $user->
getId() ?:
null,
275 'actor_name' => (string)$user->
getName(),
277 if ( $q[
'actor_user'] ===
null && User::isUsableName( $q[
'actor_name'] ) ) {
279 'Cannot create an actor for a usable name that is not an existing user: ' .
280 "user_id={$user->getId()} user_name=\"{$user->getName()}\""
283 if ( $q[
'actor_name'] ===
'' ) {
285 'Cannot create an actor for a user with no name: ' .
286 "user_id={$user->getId()} user_name=\"{$user->getName()}\""
290 $dbw->
insert(
'actor', $q, __METHOD__, [
'IGNORE' ] );
302 [
'LOCK IN SHARE MODE' ]
306 "Failed to create actor ID for " .
307 "user_id={$user->getId()} user_name=\"{$user->getName()}\""
325 self::checkDeprecation( $key );
327 if ( isset( self::$tempTables[$key] ) ) {
328 throw new InvalidArgumentException(
"Must use getInsertValuesWithTempTable() for $key" );
331 list( $text, $actor ) = self::getFieldNames( $key );
334 $ret[$key] = $user->
getId();
335 $ret[$text] = $user->
getName();
341 if ( $existingActorId !==
false ) {
342 $ret[$actor] = $existingActorId;
363 self::checkDeprecation( $key );
365 if ( isset( self::$formerTempTables[$key] ) ) {
366 wfDeprecated( __METHOD__ .
" for $key", self::$formerTempTables[$key] );
367 } elseif ( !isset( self::$tempTables[$key] ) ) {
368 throw new InvalidArgumentException(
"Must use getInsertValues() for $key" );
371 list( $text, $actor ) = self::getFieldNames( $key );
375 $ret[$key] = $user->
getId();
376 $ret[$text] = $user->
getName();
381 $user = User::newFromAnyId( $user->
getId(), $user->
getName(),
null );
385 if ( isset( self::$tempTables[$key] ) ) {
387 $callback =
function ( $pk, array $extra ) use ( $dbw, $key, $id, $func ) {
388 $t = self::$tempTables[$key];
389 $set = [
$t[
'field'] => $id ];
390 foreach (
$t[
'extra'] as $to => $from ) {
391 if ( !array_key_exists( $from, $extra ) ) {
392 throw new InvalidArgumentException(
"$func callback: \$extra[$from] is not provided" );
394 $set[$to] = $extra[$from];
398 [
$t[
'pk'] => $pk ] + $set,
406 $callback =
function ( $pk, array $extra ) {
409 } elseif ( isset( self::$tempTables[$key] ) ) {
411 $callback =
function ( $pk, array $extra ) use ( $key, $func ) {
412 $t = self::$tempTables[$key];
413 foreach (
$t[
'extra'] as $to => $from ) {
414 if ( !array_key_exists( $from, $extra ) ) {
415 throw new InvalidArgumentException(
"$func callback: \$extra[$from] is not provided" );
420 $callback =
function ( $pk, array $extra ) {
423 return [ $ret, $callback ];
448 self::checkDeprecation( $key );
462 foreach ( $users as $user ) {
463 if ( $useId && $user->getId() ) {
464 $ids[] = $user->getId();
466 $names[] = $user->getName();
468 $actorId = $user->getActorId();
470 $actors[] = $actorId;
474 list( $text, $actor ) = self::getFieldNames( $key );
479 if ( isset( self::$tempTables[$key] ) ) {
480 $t = self::$tempTables[$key];
481 $alias =
"temp_$key";
482 $tables[$alias] =
$t[
'table'];
483 $joins[$alias] = [
'JOIN',
"{$alias}.{$t['pk']} = {$t['joinPK']}" ];
484 $joinField =
"{$alias}.{$t['field']}";
488 $conds[
'actor'] = $db->
makeList( [ $joinField => $actors ], IDatabase::LIST_AND );
492 $conds[
'userid'] = $db->
makeList( [ $key => $ids ], IDatabase::LIST_AND );
495 $conds[
'username'] = $db->
makeList( [ $text => $names ], IDatabase::LIST_AND );
501 'conds' => $conds ? $db->
makeList( array_values( $conds ), IDatabase::LIST_OR ) :
'1=0',
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
This class handles the logic for the actor table migration.
const MIGRATION_STAGE_SCHEMA_COMPAT
Constant for extensions to feature-test whether $wgActorTableSchemaMigrationStage (in MW <1....
static array $formerTempTables
Fields that formerly used $tempTables Key is '$key', value is the MediaWiki version in which it was r...
isAnon( $field)
Return an SQL condition to test if a user field is anonymous.
getInsertValues(IDatabase $dbw, $key, UserIdentity $user)
Get UPDATE fields for the actor.
static array $tempTables
Define fields that use temporary tables for transitional purposes Keys are '$key',...
static array $specialFields
Define fields that use non-standard mapping Keys are the user id column name, values are arrays with ...
static newMigration()
Static constructor.
array null $joinCache
Cache for self::getJoin()
static checkDeprecation( $key)
Issue deprecation warning/error as appropriate.
getInsertValuesWithTempTable(IDatabase $dbw, $key, UserIdentity $user)
Get UPDATE fields for the actor.
getNewActorId(IDatabase $dbw, UserIdentity $user)
Attempt to assign an actor ID to the given user.
int $stage
Combination of SCHEMA_COMPAT_* constants.
isNotAnon( $field)
Return an SQL condition to test if a user field is non-anonymous.
getExistingActorId(IDatabase $db, UserIdentity $user)
Get actor ID from UserIdentity, if it exists.
static string[] $removed
Define fields that are removed for use with this class.
getWhere(IDatabase $db, $key, $users, $useId=true)
Get WHERE condition for the actor.
static string null[] $deprecated
Define fields that are deprecated for use with this class.
getJoin( $key)
Get SELECT fields and joins for the actor key.
static getFieldNames( $key)
Exception thrown when an actor can't be created.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
const SCHEMA_COMPAT_WRITE_BOTH
const SCHEMA_COMPAT_READ_NEW
const SCHEMA_COMPAT_READ_BOTH
const SCHEMA_COMPAT_WRITE_OLD
const SCHEMA_COMPAT_READ_OLD
const SCHEMA_COMPAT_WRITE_NEW