106 $this->checkIfUserExists =
true;
108 if ( isset( $options[
'checkIfUserExists'] ) ) {
109 $this->checkIfUserExists = $options[
'checkIfUserExists'];
112 if ( isset( $options[
'debugPrefix'] ) ) {
113 $this->debugPrefix = $options[
'debugPrefix'];
116 if ( isset( $options[
'reason'] ) ) {
117 $this->reason = $options[
'reason'];
121 $this->tablesJob = [];
123 if ( self::actorMigrationWriteOld() ) {
127 $this->tablesJob[
'revision'] = [
128 self::NAME_COL =>
'rev_user_text',
129 self::UID_COL =>
'rev_user',
130 self::TIME_COL =>
'rev_timestamp',
131 'uniqueKey' =>
'rev_id'
133 $this->tablesJob[
'archive'] = [
134 self::NAME_COL =>
'ar_user_text',
135 self::UID_COL =>
'ar_user',
136 self::TIME_COL =>
'ar_timestamp',
137 'uniqueKey' =>
'ar_id'
139 $this->tablesJob[
'logging'] = [
140 self::NAME_COL =>
'log_user_text',
141 self::UID_COL =>
'log_user',
142 self::TIME_COL =>
'log_timestamp',
143 'uniqueKey' =>
'log_id'
145 $this->tablesJob[
'image'] = [
146 self::NAME_COL =>
'img_user_text',
147 self::UID_COL =>
'img_user',
148 self::TIME_COL =>
'img_timestamp',
149 'uniqueKey' =>
'img_name'
151 $this->tablesJob[
'oldimage'] = [
152 self::NAME_COL =>
'oi_user_text',
153 self::UID_COL =>
'oi_user',
154 self::TIME_COL =>
'oi_timestamp'
156 $this->tablesJob[
'filearchive'] = [
157 self::NAME_COL =>
'fa_user_text',
158 self::UID_COL =>
'fa_user',
159 self::TIME_COL =>
'fa_timestamp',
160 'uniqueKey' =>
'fa_id'
163 $this->tables[
'revision'] = [
'rev_user_text',
'rev_user' ];
164 $this->tables[
'archive'] = [
'ar_user_text',
'ar_user' ];
165 $this->tables[
'logging'] = [
'log_user_text',
'log_user' ];
166 $this->tables[
'image'] = [
'img_user_text',
'img_user' ];
167 $this->tables[
'oldimage'] = [
'oi_user_text',
'oi_user' ];
168 $this->tables[
'filearchive'] = [
'fa_user_text',
'fa_user' ];
173 $this->tablesJob[
'recentchanges'] = [
'rc_user_text',
'rc_user',
'rc_timestamp' ];
175 $this->tables[
'recentchanges'] = [
'rc_user_text',
'rc_user' ];
183 if ( $this->debugPrefix ) {
184 $msg =
"{$this->debugPrefix}: $msg";
200 $atomicId = $dbw->startAtomic( __METHOD__, $dbw::ATOMIC_CANCELABLE );
202 Hooks::run(
'RenameUserPreRename', [ $this->uid, $this->old, $this->
new ] );
205 if ( $this->checkIfUserExists && !self::lockUserAndGetId( $this->old ) ) {
206 $this->
debug(
"User {$this->old} does not exist, bailing out" );
207 $dbw->cancelAtomic( __METHOD__, $atomicId );
214 $this->
debug(
"Starting rename of {$this->old} to {$this->new}" );
215 $dbw->update(
'user',
216 [
'user_name' => $this->
new,
'user_touched' => $dbw->timestamp() ],
220 if ( self::actorMigrationWriteNew() ) {
221 $dbw->update(
'actor',
222 [
'actor_name' => $this->
new ],
223 [
'actor_name' => $this->old,
'actor_user' => $this->uid ],
232 $user->load( User::READ_LATEST );
233 SessionManager::singleton()->invalidateSessionsForUser( $user );
236 $user->invalidateCache();
239 $dbw->update(
'ipblocks',
240 [
'ipb_address' => $this->
new ],
241 [
'ipb_user' => $this->uid,
'ipb_address' => $this->old ],
249 $this->
debug(
"Updating logging table for {$this->old} to {$this->new}" );
254 $dbw->update(
'logging',
255 [
'log_title' => $newTitle->getDBkey() ],
256 [
'log_type' => $logTypesOnUser,
258 'log_title' => $oldTitle->getDBkey() ],
263 foreach ( $this->tables as $table => $fieldSet ) {
264 list( $nameCol, $userCol ) = $fieldSet;
265 $dbw->update( $table,
266 [ $nameCol => $this->
new ],
267 [ $nameCol => $this->old, $userCol => $this->uid ],
281 foreach ( $this->tablesJob as $table => $params ) {
286 $res = $dbw->select( $table,
288 [ $userTextC => $this->old, $userIDC => $this->uid ],
290 [
'ORDER BY' =>
"$timestampC ASC" ]
294 $jobParams[
'table'] = $table;
295 $jobParams[
'column'] = $userTextC;
296 $jobParams[
'uidColumn'] = $userIDC;
297 $jobParams[
'timestampColumn'] = $timestampC;
302 $jobParams[
'minTimestamp'] =
'0';
303 $jobParams[
'maxTimestamp'] =
'0';
304 $jobParams[
'count'] = 0;
306 if ( isset( $params[
'uniqueKey'] ) ) {
307 $jobParams[
'uniqueKey'] = $params[
'uniqueKey'];
312 $row = $dbw->fetchObject(
$res );
314 # If there are any job rows left, add it to the queue as one job
315 if ( $jobParams[
'count'] > 0 ) {
316 $jobs[] =
Job::factory(
'renameUser', $oldTitle, $jobParams );
320 # Since the ORDER BY is ASC, set the min timestamp with first row
321 if ( $jobParams[
'count'] === 0 ) {
322 $jobParams[
'minTimestamp'] = $row->$timestampC;
324 # Keep updating the last timestamp, so it should be correct
325 # when the last item is added.
326 $jobParams[
'maxTimestamp'] = $row->$timestampC;
328 $jobParams[
'count']++;
329 # Once a job has $wgUpdateRowsPerJob rows, add it to the queue
331 $jobs[] =
Job::factory(
'renameUser', $oldTitle, $jobParams );
332 $jobParams[
'minTimestamp'] =
'0';
333 $jobParams[
'maxTimestamp'] =
'0';
334 $jobParams[
'count'] = 0;
341 $logEntry->setPerformer( $this->renamer );
342 $logEntry->setTarget( $oldTitle );
343 $logEntry->setComment( $this->reason );
344 $logEntry->setParameters( [
345 '4::olduser' => $this->old,
346 '5::newuser' => $this->
new,
347 '6::edits' => $contribs
349 $logid = $logEntry->insert();
351 foreach ( $jobs as
$job ) {
352 $job->params[
'logId'] = $logid;
358 $count = count( $jobs );
361 $this->
debug(
"Queued $count jobs for {$this->old} to {$this->new}" );
365 $dbw->endAtomic( __METHOD__ );
369 $dbw->onTransactionIdle(
function () use ( $that, $dbw, $logEntry, $logid, $fname ) {
370 $dbw->startAtomic( $fname );
373 $user->load( User::READ_LATEST );
375 $user->saveSettings();
376 Hooks::run(
'RenameUserComplete', [ $that->uid, $that->old, $that->new ] );
378 $logEntry->publish( $logid );
379 $dbw->endAtomic( $fname );
382 $this->
debug(
"Finished rename for {$this->old} to {$this->new}" );
395 [
'user_name' => $name ],
406 global $wgActorTableSchemaMigrationStage;
408 if ( !is_callable( User::class,
'getActorId' ) ) {
411 if ( !isset( $wgActorTableSchemaMigrationStage ) ) {
415 if ( defined(
'ActorMigration::MIGRATION_STAGE_SCHEMA_COMPAT' ) ) {
428 global $wgActorTableSchemaMigrationStage;
430 if ( !is_callable( User::class,
'getActorId' ) ) {
433 if ( !isset( $wgActorTableSchemaMigrationStage ) ) {
437 if ( defined(
'ActorMigration::MIGRATION_STAGE_SCHEMA_COMPAT' ) ) {