Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.37% covered (success)
97.37%
37 / 38
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
FixUserRegistration
97.37% covered (success)
97.37%
37 / 38
50.00% covered (danger)
50.00%
1 / 2
5
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 execute
97.14% covered (success)
97.14%
34 / 35
0.00% covered (danger)
0.00%
0 / 1
4
1<?php
2/**
3 * Fix the user_registration field.
4 * In particular, for values which are NULL, set them to the date of the first edit
5 *
6 * @license GPL-2.0-or-later
7 * @file
8 * @ingroup Maintenance
9 */
10
11use MediaWiki\Maintenance\Maintenance;
12use MediaWiki\User\User;
13
14// @codeCoverageIgnoreStart
15require_once __DIR__ . '/Maintenance.php';
16// @codeCoverageIgnoreEnd
17
18/**
19 * Maintenance script that fixes the user_registration field.
20 *
21 * @ingroup Maintenance
22 */
23class FixUserRegistration extends Maintenance {
24    public function __construct() {
25        parent::__construct();
26        $this->addDescription( 'Fix the user_registration field' );
27        $this->setBatchSize( 1000 );
28    }
29
30    public function execute() {
31        $dbw = $this->getPrimaryDB();
32
33        $lastId = 0;
34        do {
35            // Get user IDs which need fixing
36            $res = $dbw->newSelectQueryBuilder()
37                ->select( 'user_id' )
38                ->from( 'user' )
39                ->where( [ $dbw->expr( 'user_id', '>', $lastId ), 'user_registration' => null ] )
40                ->orderBy( 'user_id' )
41                ->limit( $this->getBatchSize() )
42                ->caller( __METHOD__ )->fetchResultSet();
43
44            foreach ( $res as $row ) {
45                $id = $row->user_id;
46                $lastId = $id;
47
48                // Get first edit time
49                $actorStore = $this->getServiceContainer()->getActorStore();
50                $userIdentity = $actorStore->getUserIdentityByUserId( $id );
51                if ( !$userIdentity ) {
52                    continue;
53                }
54
55                $timestamp = $dbw->newSelectQueryBuilder()
56                    ->select( 'MIN(rev_timestamp)' )
57                    ->from( 'revision' )
58                    ->where( [ 'rev_actor' => $userIdentity->getId() ] )
59                    ->caller( __METHOD__ )->fetchField();
60
61                // Update
62                if ( $timestamp !== null ) {
63                    $dbw->newUpdateQueryBuilder()
64                        ->update( 'user' )
65                        ->set( [ 'user_registration' => $timestamp ] )
66                        ->where( [ 'user_id' => $id ] )
67                        ->caller( __METHOD__ )->execute();
68
69                    $user = User::newFromId( $id );
70                    $user->invalidateCache();
71                    $this->output( "Set registration for #$id to $timestamp\n" );
72                } else {
73                    $this->output( "Could not find registration for #$id NULL\n" );
74                }
75            }
76            $this->output( "Waiting for replica DBs..." );
77            $this->waitForReplication();
78            $this->output( " done.\n" );
79        } while ( $res->numRows() >= $this->getBatchSize() );
80    }
81}
82
83// @codeCoverageIgnoreStart
84$maintClass = FixUserRegistration::class;
85require_once RUN_MAINTENANCE_IF_MAIN;
86// @codeCoverageIgnoreEnd