Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
PopulateUserIsTemp
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
4 / 4
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getUpdateKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 doDBUpdates
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
3
 initServices
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Fills the user_is_temp column of the user table for users created before MW 1.42.
4 *
5 * @license GPL-2.0-or-later
6 * @file
7 * @ingroup Maintenance
8 */
9
10use MediaWiki\Maintenance\LoggedUpdateMaintenance;
11use MediaWiki\User\TempUser\TempUserConfig;
12use Wikimedia\Rdbms\IDatabase;
13use Wikimedia\Rdbms\IExpression;
14use Wikimedia\Rdbms\IReadableDatabase;
15
16// @codeCoverageIgnoreStart
17require_once __DIR__ . '/Maintenance.php';
18// @codeCoverageIgnoreEnd
19
20/**
21 * Maintenance script that Fills the user_is_temp column of the user table for users created before MW 1.42.
22 *
23 * @since 1.42
24 * @ingroup Maintenance
25 */
26class PopulateUserIsTemp extends LoggedUpdateMaintenance {
27
28    private TempUserConfig $tempUserConfig;
29    private IDatabase $dbw;
30    private IReadableDatabase $dbr;
31
32    public function __construct() {
33        parent::__construct();
34        $this->addDescription( 'Populates the user_is_temp field of the user table.' );
35        $this->setBatchSize( 200 );
36    }
37
38    /** @inheritDoc */
39    protected function getUpdateKey() {
40        return __CLASS__;
41    }
42
43    /** @inheritDoc */
44    protected function doDBUpdates() {
45        $this->initServices();
46
47        if ( !$this->tempUserConfig->isKnown() ) {
48            // If temporary user auto-creation is not known, then just return early as there will be no rows to update.
49            return true;
50        }
51
52        // Generate a SelectQueryBuilder that selects all temporary users (based on the configured match patterns)
53        // which do have user_is_temp set to 0 (the default) in the the user table.
54        $queryBuilder = $this->dbr->newSelectQueryBuilder()
55            ->select( 'user_id' )
56            ->from( 'user' )
57            ->where( [
58                'user_is_temp' => 0,
59                $this->tempUserConfig->getMatchCondition( $this->dbr, 'user_name', IExpression::LIKE ),
60            ] )
61            ->limit( $this->getBatchSize() ?? 200 )
62            ->caller( __METHOD__ );
63
64        do {
65            // Get a batch of user IDs for temporary accounts that do not have user_is_temp set to 1.
66            $batch = $queryBuilder->fetchFieldValues();
67            if ( count( $batch ) ) {
68                // If there are user IDs in the batch, then update the user_is_temp column to '1' for these rows.
69                $this->dbw->newUpdateQueryBuilder()
70                    ->update( 'user' )
71                    ->set( [ 'user_is_temp' => 1 ] )
72                    ->where( [ 'user_id' => $batch ] )
73                    ->caller( __METHOD__ )
74                    ->execute();
75            }
76        } while ( count( $batch ) >= ( $this->getBatchSize() ?? 200 ) );
77
78        return true;
79    }
80
81    /**
82     * Initialise the services and database connections used by this script.
83     *
84     * This code is not in ::doDBUpdates() so that this can be skipped in unit tests
85     * and the IReadableDatabase object can be strongly typed.
86     */
87    protected function initServices(): void {
88        $this->tempUserConfig = $this->getServiceContainer()->getTempUserConfig();
89        $this->dbw = $this->getDB( DB_PRIMARY );
90        $this->dbr = $this->getDB( DB_REPLICA );
91    }
92}
93
94// @codeCoverageIgnoreStart
95$maintClass = PopulateUserIsTemp::class;
96require_once RUN_MAINTENANCE_IF_MAIN;
97// @codeCoverageIgnoreEnd