Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.75% covered (success)
93.75%
45 / 48
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
RenameUser
93.75% covered (success)
93.75%
45 / 48
66.67% covered (warning)
66.67%
2 / 3
14.05
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 initServices
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 execute
91.43% covered (success)
91.43%
32 / 35
0.00% covered (danger)
0.00%
0 / 1
12.09
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @ingroup Maintenance
5 * @author Martin Urbanec <martin.urbanec@wikimedia.cz>
6 */
7
8// @codeCoverageIgnoreStart
9require_once __DIR__ . '/Maintenance.php';
10// @codeCoverageIgnoreEnd
11
12use MediaWiki\Maintenance\Maintenance;
13use MediaWiki\RenameUser\RenameUserFactory;
14use MediaWiki\User\User;
15use MediaWiki\User\UserFactory;
16
17class RenameUser extends Maintenance {
18    /** @var UserFactory */
19    private $userFactory;
20
21    /** @var RenameUserFactory */
22    private $renameUserFactory;
23
24    public function __construct() {
25        parent::__construct();
26
27        $this->addDescription( 'Rename a user' );
28        $this->addArg( 'old-name', 'Current username of the to-be-renamed user' );
29        $this->addArg( 'new-name', 'New username of the to-be-renamed user' );
30        $this->addOption( 'performer', 'Performer of the rename action', false, true );
31        $this->addOption( 'reason', 'Reason of the rename', false, true );
32        $this->addOption( 'force-global-detach',
33            'Rename the local user even if it is attached to a global account' );
34        $this->addOption( 'suppress-redirect', 'Don\'t create redirects when moving pages' );
35        $this->addOption( 'skip-page-moves', 'Don\'t move associated user pages' );
36    }
37
38    private function initServices() {
39        $services = $this->getServiceContainer();
40        $this->userFactory = $services->getUserFactory();
41        $this->renameUserFactory = $services->getRenameUserFactory();
42    }
43
44    public function execute() {
45        $this->initServices();
46
47        $oldName = $this->getArg( 'old-name' );
48        $newName = $this->getArg( 'new-name' );
49        $reason = $this->getOption( 'reason' ) ?? '';
50
51        $oldUser = $this->userFactory->newFromName( $oldName );
52        $newUser = $this->userFactory->newFromName( $newName );
53
54        if ( !$oldUser ) {
55            $this->fatalError( 'The specified old username is invalid.' );
56        } elseif ( !$oldUser->isRegistered() ) {
57            $this->fatalError( 'The user does not exist.' );
58        }
59        if ( !$newUser ) {
60            $this->fatalError( 'The specified new username is invalid.' );
61        } elseif ( $newUser->isRegistered() ) {
62            $this->fatalError( 'New username must be free.' );
63        }
64
65        if ( $this->getOption( 'performer' ) === null ) {
66            $performer = User::newSystemUser( User::MAINTENANCE_SCRIPT_USER, [ 'steal' => true ] );
67        } else {
68            $performer = $this->userFactory->newFromName( $this->getOption( 'performer' ) );
69        }
70
71        if ( !( $performer instanceof User ) || !$performer->isRegistered() ) {
72            $this->fatalError( 'Performer does not exist.' );
73        }
74
75        $rename = $this->renameUserFactory->newRenameUser( $performer, $oldUser, $newName, $reason, [
76            'forceGlobalDetach' => $this->getOption( 'force-global-detach' ),
77            'movePages' => !$this->getOption( 'skip-page-moves' ),
78            'suppressRedirect' => $this->getOption( 'suppress-redirect' ),
79        ] );
80        $status = $rename->renameUnsafe();
81
82        if ( $status->isGood() ) {
83            $this->output( "Successfully renamed user.\n" );
84        } else {
85            if ( $status->isOK() ) {
86                $this->output( "Successfully renamed user with some warnings.\n" );
87                foreach ( $status->getMessages() as $msg ) {
88                    $this->output( '  - ' . wfMessage( $msg )->plain() );
89                }
90            } else {
91                $out = "Failed to rename user:\n";
92                foreach ( $status->getMessages() as $msg ) {
93                    $out = $out . '  - ' . wfMessage( $msg )->plain() . "\n";
94                }
95                $this->fatalError( $out );
96            }
97        }
98    }
99}
100
101// @codeCoverageIgnoreStart
102$maintClass = RenameUser::class;
103require_once RUN_MAINTENANCE_IF_MAIN;
104// @codeCoverageIgnoreEnd