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 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup Maintenance
22 */
23
24use MediaWiki\Maintenance\LoggedUpdateMaintenance;
25use MediaWiki\User\TempUser\TempUserConfig;
26use Wikimedia\Rdbms\IDatabase;
27use Wikimedia\Rdbms\IExpression;
28use Wikimedia\Rdbms\IReadableDatabase;
29
30// @codeCoverageIgnoreStart
31require_once __DIR__ . '/Maintenance.php';
32// @codeCoverageIgnoreEnd
33
34/**
35 * Maintenance script that Fills the user_is_temp column of the user table for users created before MW 1.42.
36 *
37 * @since 1.42
38 * @ingroup Maintenance
39 */
40class PopulateUserIsTemp extends LoggedUpdateMaintenance {
41
42    private TempUserConfig $tempUserConfig;
43    private IDatabase $dbw;
44    private IReadableDatabase $dbr;
45
46    public function __construct() {
47        parent::__construct();
48        $this->addDescription( 'Populates the user_is_temp field of the user table.' );
49        $this->setBatchSize( 200 );
50    }
51
52    /** @inheritDoc */
53    protected function getUpdateKey() {
54        return __CLASS__;
55    }
56
57    /** @inheritDoc */
58    protected function doDBUpdates() {
59        $this->initServices();
60
61        if ( !$this->tempUserConfig->isKnown() ) {
62            // If temporary user auto-creation is not known, then just return early as there will be no rows to update.
63            return true;
64        }
65
66        // Generate a SelectQueryBuilder that selects all temporary users (based on the configured match patterns)
67        // which do have user_is_temp set to 0 (the default) in the the user table.
68        $queryBuilder = $this->dbr->newSelectQueryBuilder()
69            ->select( 'user_id' )
70            ->from( 'user' )
71            ->where( [
72                'user_is_temp' => 0,
73                $this->tempUserConfig->getMatchCondition( $this->dbr, 'user_name', IExpression::LIKE ),
74            ] )
75            ->limit( $this->getBatchSize() ?? 200 )
76            ->caller( __METHOD__ );
77
78        do {
79            // Get a batch of user IDs for temporary accounts that do not have user_is_temp set to 1.
80            $batch = $queryBuilder->fetchFieldValues();
81            if ( count( $batch ) ) {
82                // If there are user IDs in the batch, then update the user_is_temp column to '1' for these rows.
83                $this->dbw->newUpdateQueryBuilder()
84                    ->update( 'user' )
85                    ->set( [ 'user_is_temp' => 1 ] )
86                    ->where( [ 'user_id' => $batch ] )
87                    ->caller( __METHOD__ )
88                    ->execute();
89            }
90        } while ( count( $batch ) >= ( $this->getBatchSize() ?? 200 ) );
91
92        return true;
93    }
94
95    /**
96     * Initialise the services and database connections used by this script.
97     *
98     * This code is not in ::doDBUpdates() so that this can be skipped in unit tests
99     * and the IReadableDatabase object can be strongly typed.
100     *
101     * @return void
102     */
103    protected function initServices(): void {
104        $this->tempUserConfig = $this->getServiceContainer()->getTempUserConfig();
105        $this->dbw = $this->getDB( DB_PRIMARY );
106        $this->dbr = $this->getDB( DB_REPLICA );
107    }
108}
109
110// @codeCoverageIgnoreStart
111$maintClass = PopulateUserIsTemp::class;
112require_once RUN_MAINTENANCE_IF_MAIN;
113// @codeCoverageIgnoreEnd