Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
PopulateCentralId
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 3
56
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getUpdateKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doDbUpdates
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3namespace MediaWiki\Extension\GlobalBlocking\Maintenance;
4
5$IP = getenv( 'MW_INSTALL_PATH' );
6if ( $IP === false ) {
7    $IP = __DIR__ . '/../../..';
8}
9require_once "$IP/maintenance/Maintenance.php";
10
11use LoggedUpdateMaintenance;
12use MediaWiki\Extension\GlobalBlocking\GlobalBlocking;
13use MediaWiki\MediaWikiServices;
14use MediaWiki\User\CentralId\CentralIdLookup;
15use MediaWiki\WikiMap\WikiMap;
16
17/**
18 * Maintenance script for migrating the blocker from a username to a
19 * central id.
20 */
21class PopulateCentralId extends LoggedUpdateMaintenance {
22
23    public function __construct() {
24        parent::__construct();
25        $this->requireExtension( 'GlobalBlocking' );
26    }
27
28    /**
29     * @inheritDoc
30     */
31    public function getUpdateKey() {
32        return 'GlobalBlockingPopulateCentralId';
33    }
34
35    /**
36     * @inheritDoc
37     */
38    public function doDbUpdates() {
39        $dbr = GlobalBlocking::getReplicaGlobalBlockingDatabase();
40        $dbw = GlobalBlocking::getPrimaryGlobalBlockingDatabase();
41        $services = MediaWikiServices::getInstance();
42        $lbFactory = $services->getDBLoadBalancerFactory();
43        $lookup = $services->getCentralIdLookup();
44        $wikiId = WikiMap::getCurrentWikiId();
45
46        $batchSize = $this->getBatchSize();
47        $count = 0;
48        $failed = 0;
49        $lastBlock = $dbr->newSelectQueryBuilder()
50            ->select( 'MAX(gb_id)' )
51            ->from( 'globalblocks' )
52            ->caller( __METHOD__ )
53            ->fetchField();
54        if ( !$lastBlock ) {
55            $this->output( "The globalblocks table seems to be empty.\n" );
56            return true;
57        }
58
59        for ( $min = 0; $min < $lastBlock; $min += $batchSize ) {
60            $max = $min + $batchSize;
61            $this->output( "Now processing global blocks with id between {$min} and {$max}...\n" );
62
63            $res = $dbr->newSelectQueryBuilder()
64                ->select( [ 'gb_id', 'gb_by' ] )
65                ->from( 'globalblocks' )
66                ->where( [
67                    'gb_by_central_id' => null,
68                    "gb_by_wiki" => $wikiId,
69                    $dbr->expr( 'gb_id', '>=', $min ),
70                    $dbr->expr( 'gb_id', '<=', $max ),
71                ] )
72                ->caller( __METHOD__ )
73                ->fetchResultSet();
74
75            foreach ( $res as $row ) {
76                $centralId = $lookup->centralIdFromName( $row->gb_by, CentralIdLookup::AUDIENCE_RAW );
77                if ( $centralId === 0 ) {
78                    $failed++;
79                    continue;
80                }
81                $dbw->newUpdateQueryBuilder()
82                    ->update( 'globalblocks' )
83                    ->set( [ 'gb_by_central_id' => $centralId ] )
84                    ->where( [ 'gb_id' => $row->gb_id ] )
85                    ->caller( __METHOD__ )
86                    ->execute();
87            }
88
89            $count += $dbw->affectedRows();
90            $lbFactory->waitForReplication();
91        }
92        $this->output( "Completed migration, updated $count row(s), migration failed for $failed row(s).\n" );
93
94        return true;
95    }
96}
97
98$maintClass = PopulateCentralId::class;
99require_once RUN_MAINTENANCE_IF_MAIN;