Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 85 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
SendForceRenameNotification | |
0.00% |
0 / 79 |
|
0.00% |
0 / 4 |
210 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 58 |
|
0.00% |
0 / 1 |
90 | |||
getQueuedCount | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
getLocalizedText | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 |
1 | <?php |
2 | |
3 | use MediaWiki\Extension\CentralAuth\CentralAuthServices; |
4 | use MediaWiki\Extension\CentralAuth\UsersToRename\UsersToRenameDatabaseUpdates; |
5 | use MediaWiki\MassMessage\Job\MassMessageServerSideJob; |
6 | use MediaWiki\MediaWikiServices; |
7 | use MediaWiki\Title\Title; |
8 | use MediaWiki\WikiMap\WikiMap; |
9 | |
10 | $IP = getenv( 'MW_INSTALL_PATH' ); |
11 | if ( $IP === false ) { |
12 | $IP = __DIR__ . '/../../..'; |
13 | } |
14 | require_once "$IP/maintenance/Maintenance.php"; |
15 | |
16 | /** |
17 | * Script to notify users listed in the users_to_rename table |
18 | * that they will be renamed. Requires the MassMessage extension |
19 | * |
20 | * Setup: |
21 | * - A directory with localized message files, named in the format of "$langCode.txt". |
22 | * The string "{{WIKI}}" will be expanded to the current database name |
23 | * - A directory with localized subject files, named in the format of "$langCode.txt". |
24 | * A file for "en" must exist as it is the base fallback. |
25 | */ |
26 | class SendForceRenameNotification extends Maintenance { |
27 | public function __construct() { |
28 | parent::__construct(); |
29 | |
30 | $this->requireExtension( 'CentralAuth' ); |
31 | $this->requireExtension( 'MassMessage' ); |
32 | |
33 | $this->addOption( 'message', 'Location of directory with messages', true, true ); |
34 | $this->addOption( 'subject', 'Location of directory with subjects', true, true ); |
35 | $this->addOption( 'sleep', 'How long to sleep for', false, true ); |
36 | $this->setBatchSize( 100 ); |
37 | } |
38 | |
39 | public function execute() { |
40 | $message = $this->getLocalizedText( $this->getOption( 'message' ) ); |
41 | $message = str_replace( '{{WIKI}}', WikiMap::getCurrentWikiId(), $message ); |
42 | $message .= " ~~~~~\n<!-- SUL finalisation notification -->"; |
43 | $databaseManager = CentralAuthServices::getDatabaseManager(); |
44 | $dbw = $databaseManager->getCentralPrimaryDB(); |
45 | $updates = new UsersToRenameDatabaseUpdates( $dbw ); |
46 | $commonParams = [ |
47 | 'subject' => $this->getLocalizedText( $this->getOption( 'subject' ) ), |
48 | ]; |
49 | |
50 | $services = MediaWikiServices::getInstance(); |
51 | $lbFactory = $services->getDBLoadBalancerFactory(); |
52 | $namespaceInfo = $services->getNamespaceInfo(); |
53 | $jobQueueGroup = $services->getJobQueueGroup(); |
54 | $linkBatchFactory = $services->getLinkBatchFactory(); |
55 | |
56 | while ( true ) { |
57 | $jobs = []; |
58 | $markNotified = []; |
59 | $rows = $updates->findUsers( WikiMap::getCurrentWikiId(), 0, $this->mBatchSize ); |
60 | if ( $rows->numRows() === 0 ) { |
61 | break; |
62 | } |
63 | $lb = $linkBatchFactory->newLinkBatch(); |
64 | foreach ( $rows as $row ) { |
65 | $title = Title::makeTitleSafe( NS_USER_TALK, $row->utr_name ); |
66 | if ( !$title ) { |
67 | $this->output( "ERROR: Invalid username for {$row->utr_name}\n" ); |
68 | continue; |
69 | } |
70 | $lb->addObj( $title ); |
71 | } |
72 | $lb->execute(); |
73 | foreach ( $rows as $row ) { |
74 | $title = $namespaceInfo->getCanonicalName( NS_USER_TALK ) . ':' . $row->utr_name; |
75 | $titleObj = Title::newFromText( $title ); |
76 | if ( $titleObj->isRedirect() ) { |
77 | // @fixme find a way to notify users with a redirected user-talk |
78 | $this->output( "Skipping {$title} because it is a redirect\n" ); |
79 | $updates->markRedirectSkipped( $row->utr_name, $row->utr_wiki ); |
80 | continue; |
81 | } |
82 | $jobs[] = new MassMessageServerSideJob( |
83 | Title::newFromText( $title ), |
84 | [ |
85 | 'title' => $title, |
86 | 'message' => str_replace( '{{subst:PAGENAME}}', $row->utr_name, $message ) |
87 | ] + $commonParams |
88 | ); |
89 | $this->output( "Will notify {$row->utr_name}\n" ); |
90 | $markNotified[] = $row; |
91 | } |
92 | |
93 | $count = count( $jobs ); |
94 | $this->output( "Queued job for $count users.\n" ); |
95 | $jobQueueGroup->push( $jobs ); |
96 | foreach ( $markNotified as $row ) { |
97 | $updates->markNotified( $row->utr_name, $row->utr_wiki ); |
98 | } |
99 | $this->output( "Waiting for replicas..." ); |
100 | // users_to_rename |
101 | $databaseManager->waitForReplication(); |
102 | // And on the local wiki! |
103 | $lbFactory->waitForReplication(); |
104 | |
105 | $this->output( " done.\n" ); |
106 | $queued = $this->getQueuedCount(); |
107 | while ( $queued > 100000 ) { |
108 | $this->output( "Currently $queued jobs, sleeping for 5 seconds...\n" ); |
109 | sleep( 5 ); |
110 | $queued = $this->getQueuedCount(); |
111 | } |
112 | } |
113 | } |
114 | |
115 | /** |
116 | * @return int |
117 | */ |
118 | protected function getQueuedCount() { |
119 | $group = MediaWikiServices::getInstance()->getJobQueueGroup(); |
120 | $queue = $group->get( 'MassMessageServerSideJob' ); |
121 | $pending = $queue->getSize(); |
122 | $claimed = $queue->getAcquiredCount(); |
123 | $abandoned = $queue->getAbandonedCount(); |
124 | $active = max( $claimed - $abandoned, 0 ); |
125 | |
126 | return $active + $pending; |
127 | } |
128 | |
129 | /** |
130 | * @param string $dir |
131 | * |
132 | * @return string |
133 | */ |
134 | protected function getLocalizedText( $dir ) { |
135 | $langCode = $this->getConfig()->get( 'LanguageCode' ); |
136 | $fallbacks = MediaWikiServices::getInstance()->getLanguageFallback()->getAll( $langCode ); |
137 | array_unshift( $fallbacks, $langCode ); |
138 | foreach ( $fallbacks as $code ) { |
139 | if ( file_exists( "$dir/$code.txt" ) ) { |
140 | return trim( file_get_contents( "$dir/$code.txt" ) ); |
141 | } |
142 | } |
143 | |
144 | $this->fatalError( "Could not find a valid localized file for $langCode." ); |
145 | } |
146 | } |
147 | |
148 | $maintClass = SendForceRenameNotification::class; |
149 | require_once RUN_MAINTENANCE_IF_MAIN; |