107 $this->checkIfUserExists =
true;
109 if ( isset(
$options[
'checkIfUserExists'] ) ) {
110 $this->checkIfUserExists =
$options[
'checkIfUserExists'];
113 if ( isset(
$options[
'debugPrefix'] ) ) {
114 $this->debugPrefix =
$options[
'debugPrefix'];
117 if ( isset(
$options[
'reason'] ) ) {
122 $this->tablesJob = [];
127 $this->
tables[
'image'] = [
'img_user_text',
'img_user' ];
128 $this->
tables[
'oldimage'] = [
'oi_user_text',
'oi_user' ];
129 $this->
tables[
'filearchive'] = [
'fa_user_text',
'fa_user' ];
134 $this->tablesJob[
'revision'] = [
135 self::NAME_COL =>
'rev_user_text',
136 self::UID_COL =>
'rev_user',
137 self::TIME_COL =>
'rev_timestamp',
138 'uniqueKey' =>
'rev_id'
140 $this->tablesJob[
'archive'] = [
141 self::NAME_COL =>
'ar_user_text',
142 self::UID_COL =>
'ar_user',
143 self::TIME_COL =>
'ar_timestamp',
144 'uniqueKey' =>
'ar_id'
146 $this->tablesJob[
'logging'] = [
147 self::NAME_COL =>
'log_user_text',
148 self::UID_COL =>
'log_user',
149 self::TIME_COL =>
'log_timestamp',
150 'uniqueKey' =>
'log_id'
153 $this->
tables[
'revision'] = [
'rev_user_text',
'rev_user' ];
154 $this->
tables[
'archive'] = [
'ar_user_text',
'ar_user' ];
155 $this->
tables[
'logging'] = [
'log_user_text',
'log_user' ];
159 $this->tablesJob[
'recentchanges'] = [
'rc_user_text',
'rc_user',
'rc_timestamp' ];
161 $this->
tables[
'recentchanges'] = [
'rc_user_text',
'rc_user' ];
165 Hooks::run(
'RenameUserSQL', [ $this ] );
169 if ( $this->debugPrefix ) {
170 $msg =
"{$this->debugPrefix}: $msg";
186 $dbw->startAtomic( __METHOD__ );
188 Hooks::run(
'RenameUserPreRename', [ $this->uid, $this->old, $this->
new ] );
191 if ( $this->checkIfUserExists && !self::lockUserAndGetId( $this->old ) ) {
192 $this->
debug(
"User {$this->old} does not exist, bailing out" );
199 $this->
debug(
"Starting rename of {$this->old} to {$this->new}" );
200 $dbw->update(
'user',
201 [
'user_name' => $this->
new,
'user_touched' => $dbw->timestamp() ],
202 [
'user_name' => $this->old,
'user_id' => $this->uid ],
206 $dbw->update(
'actor',
207 [
'actor_name' => $this->
new ],
208 [
'actor_name' => $this->old,
'actor_user' => $this->uid ],
217 if ( class_exists( SessionManager::class ) &&
218 is_callable( [ SessionManager::singleton(),
'invalidateSessionsForUser' ] )
220 $user->load( User::READ_LATEST );
221 SessionManager::singleton()->invalidateSessionsForUser( $user );
223 $authUser =
$wgAuth->getUserInstance( $user );
224 $authUser->resetAuthToken();
228 $user->invalidateCache();
231 $dbw->update(
'ipblocks',
232 [
'ipb_address' => $this->
new ],
233 [
'ipb_user' => $this->uid,
'ipb_address' => $this->old ],
239 $oldTitle = Title::makeTitle( NS_USER, $this->old );
240 $newTitle = Title::makeTitle( NS_USER, $this->
new );
241 $this->
debug(
"Updating logging table for {$this->old} to {$this->new}" );
245 $dbw->update(
'logging',
246 [
'log_title' => $newTitle->getDBkey() ],
247 [
'log_type' => $logTypesOnUser,
248 'log_namespace' => NS_USER,
254 foreach ( $this->
tables as $table => $fieldSet ) {
255 list( $nameCol, $userCol ) = $fieldSet;
256 $dbw->update( $table,
257 [ $nameCol => $this->
new ],
258 [ $nameCol => $this->old, $userCol => $this->uid ],
272 foreach ( $this->tablesJob as $table =>
$params ) {
277 $res = $dbw->select( $table,
279 [ $userTextC => $this->old, $userIDC => $this->uid ],
281 [
'ORDER BY' =>
"$timestampC ASC" ]
285 $jobParams[
'table'] = $table;
286 $jobParams[
'column'] = $userTextC;
287 $jobParams[
'uidColumn'] = $userIDC;
288 $jobParams[
'timestampColumn'] = $timestampC;
293 $jobParams[
'minTimestamp'] =
'0';
294 $jobParams[
'maxTimestamp'] =
'0';
295 $jobParams[
'count'] = 0;
297 if ( isset(
$params[
'uniqueKey'] ) ) {
298 $jobParams[
'uniqueKey'] =
$params[
'uniqueKey'];
303 $row = $dbw->fetchObject(
$res );
305 # If there are any job rows left, add it to the queue as one job
306 if ( $jobParams[
'count'] > 0 ) {
311 # Since the ORDER BY is ASC, set the min timestamp with first row
312 if ( $jobParams[
'count'] === 0 ) {
313 $jobParams[
'minTimestamp'] = $row->$timestampC;
315 # Keep updating the last timestamp, so it should be correct
316 # when the last item is added.
317 $jobParams[
'maxTimestamp'] = $row->$timestampC;
319 $jobParams[
'count']++;
320 # Once a job has $wgUpdateRowsPerJob rows, add it to the queue
323 $jobParams[
'minTimestamp'] =
'0';
324 $jobParams[
'maxTimestamp'] =
'0';
325 $jobParams[
'count'] = 0;
328 $dbw->freeResult(
$res );
333 $logEntry->setPerformer( $this->renamer );
335 $logEntry->setComment( $this->reason );
336 $logEntry->setParameters( [
337 '4::olduser' => $this->old,
338 '5::newuser' => $this->
new,
339 '6::edits' => $contribs
341 $logid = $logEntry->insert();
343 foreach ( $jobs as
$job ) {
344 $job->params[
'logId'] = $logid;
350 $count = count( $jobs );
352 JobQueueGroup::singleton()->push( $jobs );
353 $this->
debug(
"Queued $count jobs for {$this->old} to {$this->new}" );
357 $dbw->endAtomic( __METHOD__ );
361 $dbw->onTransactionIdle(
function () use ( $that, $dbw, $logEntry, $logid,
$fname ) {
362 $dbw->startAtomic(
$fname );
365 $user->load( User::READ_LATEST );
367 if ( class_exists( AuthManager::class ) ) {
368 AuthManager::callLegacyAuthPlugin(
'updateExternalDB', [ $user ] );
371 $wgAuth->updateExternalDB( $user );
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 ],
$wgUpdateRowsPerJob
Number of rows to update per job.
$wgAuth $wgAuth
Authentication plugin.
int $wgActorTableSchemaMigrationStage
Actor table schema migration stage.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
wfQueriesMustScale()
Should low-performance queries be disabled?
if(defined( 'MW_SETUP_CALLBACK')) $fname
Customization point after all loading (constants, functions, classes, DefaultSettings,...
static factory( $command, Title $title, $params=[])
Create the appropriate object to handle a specific job.
Class for creating new log entries and inserting them into the database.
Class which performs the actual renaming of users.
static getActorMigrationStage()
Fetch the core actor table schema migration stage.
array $tablesJob
tables => fields to be updated in a deferred job
array $tables
The tables => fields to be updated.
string $old
The old username.
User $renamer
User object of the user performing the rename, for logging purposes.
static lockUserAndGetId( $name)
string $reason
Reason to be used in the log entry.
string $debugPrefix
A prefix to use in all debug log messages.
rename()
Do the rename operation.
const CONTRIB_JOB
Users with more than this number of edits will have their rename operation deferred via the job queue...
bool $checkIfUserExists
Flag that can be set to false, in case another process has already started the updates and the old us...
string $new
The new username.
__construct( $old, $new, $uid, User $renamer, $options=[])
Constructor.
static getLogTypesOnUser()
List log type for which the target is a user Thus if the given target is in NS_MAIN we can alter it t...
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
static newFromId( $id)
Static factory method for creation from a given user ID.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
const MIGRATION_WRITE_BOTH
The wiki should then use memcached to cache various data To use multiple just add more items to the array To increase the weight of a make its entry a array("192.168.0.1:11211", 2))
In both all secondary updates will be triggered handle like object that caches derived data representing a and can trigger updates of cached copies of that e g in the links tables
if(count( $args)< 1) $job