Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 93
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialGlobalRenameProgress
0.00% covered (danger)
0.00%
0 / 93
0.00% covered (danger)
0.00%
0 / 9
380
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getFormFields
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 alterForm
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 checkCachePurge
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 showCurrentRenames
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 onSubmit
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 1
72
 requiresWrite
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 requiresUnblock
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDisplayFormat
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\CentralAuth\Special;
4
5use HTMLForm;
6use MediaWiki\Extension\CentralAuth\CentralAuthUIService;
7use MediaWiki\Extension\CentralAuth\GlobalRename\GlobalRenameFactory;
8use MediaWiki\Extension\CentralAuth\GlobalRename\GlobalRenameUserStatus;
9use MediaWiki\Extension\CentralAuth\User\CentralAuthUser;
10use MediaWiki\Html\Html;
11use MediaWiki\Logger\LoggerFactory;
12use MediaWiki\SpecialPage\FormSpecialPage;
13use MediaWiki\User\UserNameUtils;
14use MediaWiki\WikiMap\WikiMap;
15use Xml;
16
17class SpecialGlobalRenameProgress extends FormSpecialPage {
18
19    /** @var UserNameUtils */
20    private $userNameUtils;
21
22    /** @var CentralAuthUIService */
23    private $uiService;
24    private GlobalRenameFactory $globalRenameFactory;
25
26    /**
27     * @var GlobalRenameUserStatus
28     */
29    private $renameuserStatus;
30
31    public function __construct(
32        UserNameUtils $userNameUtils,
33        CentralAuthUIService $uiService,
34        GlobalRenameFactory $globalRenameFactory
35    ) {
36        parent::__construct( 'GlobalRenameProgress' );
37        $this->userNameUtils = $userNameUtils;
38        $this->uiService = $uiService;
39        $this->globalRenameFactory = $globalRenameFactory;
40    }
41
42    /** @inheritDoc */
43    public function getFormFields() {
44        return [
45            'username' => [
46                'id' => 'mw-renameprogress-username',
47                'label-message' => 'centralauth-rename-progress-username',
48                'type' => 'text',
49                'name' => 'username',
50                'default' => $this->getRequest()->getVal( 'username', $this->par ),
51            ]
52        ];
53    }
54
55    /** @inheritDoc */
56    public function alterForm( HTMLForm $htmlForm ) {
57        $this->addHelpLink( 'Extension:CentralAuth' );
58        $htmlForm
59            ->setMethod( 'get' )
60            ->setTitle( $this->getPageTitle() )
61            ->setSubmitText( $this->msg( 'centralauth-rename-viewprogress' )->text() )
62            ->setWrapperLegendMsg( 'globalrenameprogress-legend' );
63    }
64
65    /**
66     * There's a race condition of some kind in cache purging (T94491),
67     * so see if the cache still thinks they're being renamed and purge
68     * it if it's wrong
69     *
70     * @param string $name
71     */
72    public function checkCachePurge( $name ) {
73        $ca = CentralAuthUser::getInstanceByName( $name );
74        if ( $ca->renameInProgress() ) {
75            $ca->quickInvalidateCache();
76        }
77    }
78
79    private function showCurrentRenames() {
80        $renames = GlobalRenameUserStatus::getInProgressRenames( $this->getUser() );
81
82        if ( !$renames ) {
83            return;
84        }
85
86        $html = "<ul>\n";
87        foreach ( $renames as $oldname => $newname ) {
88            $html .= '<li>' .
89                $this->msg( 'centralauth-rename-progress-item' )
90                    ->params( $oldname, $newname )->parse() .
91                "</li>\n";
92        }
93
94        $html .= "</ul>\n";
95        $html = $this->msg( 'centralauth-rename-progress-list-header' )->escaped() . $html;
96        $this->getOutput()->addHTML( $html );
97    }
98
99    /** @inheritDoc */
100    public function onSubmit( array $data ) {
101        if ( !isset( $data['username'] ) ) {
102            $this->showCurrentRenames();
103            return false;
104        }
105        $name = $this->userNameUtils->getCanonical( $data['username'], UserNameUtils::RIGOR_USABLE );
106        if ( !$name ) {
107            $this->showCurrentRenames();
108            return false;
109        }
110
111        $out = $this->getOutput();
112        $out->addBacklinkSubtitle( $this->getPageTitle() );
113
114        $this->renameuserStatus = $this->globalRenameFactory->newGlobalRenameUserStatus( $name );
115        $names = $this->renameuserStatus->getNames();
116        if ( !$names ) {
117            $this->checkCachePurge( $name );
118            $out->addWikiMsg( 'centralauth-rename-notinprogress', $name );
119            $this->getForm()->prepareForm()->displayForm( false );
120            $this->uiService->showRenameLogExtract( $this->getContext(), $name );
121            return true;
122        }
123
124        [ $oldName, $newName ] = $names;
125
126        $statuses = $this->renameuserStatus->getStatuses();
127
128        $this->getForm()->prepareForm()->displayForm( false );
129        // $newname will always be defined since we check
130        // for 0 result rows above
131        $caUser = CentralAuthUser::getInstanceByName( $newName );
132        $attached = $caUser->listAttached();
133        foreach ( $attached as $wiki ) {
134            // If it's not in the db table, and there is
135            // an attached acount, assume it's done.
136            if ( !isset( $statuses[$wiki] ) ) {
137                $statuses[$wiki] = 'done';
138            }
139        }
140        ksort( $statuses );
141        $table = Html::openElement( 'table', [ 'class' => 'wikitable sortable' ] );
142        $table .= Html::openElement( 'thead' );
143        $table .= Html::openElement( 'tr' );
144        $table .= Html::element( 'th', [],
145            $this->msg( 'centralauth-rename-table-domain' )->text() );
146        $table .= Html::element( 'th', [],
147            $this->msg( 'centralauth-rename-table-status' )->text() );
148        $table .= Html::closeElement( 'tr' );
149        $table .= Html::closeElement( 'thead' );
150        $table .= Html::openElement( 'tbody' );
151        $logger = LoggerFactory::getInstance( 'CentralAuth' );
152        foreach ( $statuses as $wiki => $status ) {
153            $wikiReference = WikiMap::getWiki( $wiki );
154            if ( !$wikiReference ) {
155                $logger->warning( __METHOD__ . ': invalid wiki: ' . $wiki );
156                continue;
157            }
158
159            $table .= Html::openElement( 'tr' );
160            $table .= Html::element( 'td', [], $wikiReference->getDisplayName() );
161            // Messages used: centralauth-rename-table-status-inprogress
162            // centralauth-rename-table-status-queued, centralauth-rename-table-status-done
163            $table .= Html::rawElement( 'td', [],
164                $this->msg( "centralauth-rename-table-status-$status" )->parse() );
165            $table .= Html::closeElement( 'tr' );
166        }
167        $table .= Html::closeElement( 'tbody' );
168        $table .= Html::closeElement( 'table' );
169        $fieldset = Xml::fieldset(
170            $this->msg( 'centralauth-rename-progress-fieldset' )->text(), $table );
171
172        $this->uiService->showRenameLogExtract( $this->getContext(), $newName );
173        $out->addHTML( $fieldset );
174        $out->addModuleStyles( 'jquery.tablesorter.styles' );
175        $out->addModules( 'jquery.tablesorter' );
176        return true;
177    }
178
179    public function requiresWrite() {
180        return false;
181    }
182
183    public function requiresUnblock() {
184        return false;
185    }
186
187    /** @inheritDoc */
188    protected function getDisplayFormat() {
189        return 'ooui';
190    }
191}