Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 63 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
MigratePreferences | |
0.00% |
0 / 57 |
|
0.00% |
0 / 4 |
132 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
doDBUpdates | |
0.00% |
0 / 44 |
|
0.00% |
0 / 1 |
30 | |||
updateUser | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 | |||
getUpdateKey | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace LoginNotify\Maintenance; |
4 | |
5 | use BatchRowIterator; |
6 | use LoggedUpdateMaintenance; |
7 | use MediaWiki\MediaWikiServices; |
8 | use MediaWiki\User\User; |
9 | use MediaWiki\WikiMap\WikiMap; |
10 | use RecursiveIteratorIterator; |
11 | |
12 | $IP = getenv( 'MW_INSTALL_PATH' ); |
13 | if ( $IP === false ) { |
14 | $IP = __DIR__ . '/../../..'; |
15 | } |
16 | |
17 | require_once "$IP/maintenance/Maintenance.php"; |
18 | |
19 | /** |
20 | * Cleans up old preference values |
21 | */ |
22 | class MigratePreferences extends LoggedUpdateMaintenance { |
23 | |
24 | // Previously, these constants were used by Hooks to force different per-user defaults |
25 | private const OPTIONS_FAKE_TRUTH = 2; |
26 | private const OPTIONS_FAKE_FALSE = 'fake-false'; |
27 | |
28 | /** @var bool[] */ |
29 | private static $mapping = [ |
30 | self::OPTIONS_FAKE_FALSE => false, |
31 | self::OPTIONS_FAKE_TRUTH => true, |
32 | ]; |
33 | |
34 | public function __construct() { |
35 | parent::__construct(); |
36 | $this->addDescription( 'Cleans up old-style preferences used by LoginNotify' ); |
37 | $this->setBatchSize( 500 ); |
38 | } |
39 | |
40 | /** |
41 | * Do the actual work. All child classes will need to implement this. |
42 | * Return true to log the update as done or false (usually on failure). |
43 | * @return bool |
44 | */ |
45 | protected function doDBUpdates() { |
46 | $dbr = $this->getDB( DB_REPLICA, 'vslow' ); |
47 | $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); |
48 | |
49 | $iterator = new BatchRowIterator( $dbr, |
50 | [ 'user_properties', 'user' ], |
51 | [ 'up_user', 'up_property' ], |
52 | $this->getBatchSize() |
53 | ); |
54 | $iterator->addConditions( [ |
55 | 'user_id=up_user', |
56 | 'up_property' => [ |
57 | 'echo-subscriptions-web-login-fail', |
58 | 'echo-subscriptions-web-login-success', |
59 | 'echo-subscriptions-email-login-fail', |
60 | 'echo-subscriptions-email-login-success', |
61 | ], |
62 | 'up_value' => [ |
63 | self::OPTIONS_FAKE_TRUTH, |
64 | self::OPTIONS_FAKE_FALSE, |
65 | ], |
66 | ] ); |
67 | $iterator->setFetchColumns( [ '*' ] ); |
68 | $iterator->setCaller( __METHOD__ ); |
69 | |
70 | $lastRow = (object)[ 'user_id' => 0 ]; |
71 | $optionsToUpdate = []; |
72 | $rows = 0; |
73 | $total = 0; |
74 | $iterator = new RecursiveIteratorIterator( $iterator ); |
75 | foreach ( $iterator as $row ) { |
76 | $userId = $row->user_id; |
77 | $option = $row->up_property; |
78 | $value = $row->up_value; |
79 | |
80 | if ( $userId != $lastRow->user_id ) { |
81 | $rows += $this->updateUser( $lastRow, $optionsToUpdate ); |
82 | if ( $rows >= $this->getBatchSize() ) { |
83 | $this->output( " Updated {$rows} rows up to user ID {$lastRow->user_id}\n" ); |
84 | $lbFactory->waitForReplication( [ 'wiki' => WikiMap::getCurrentWikiId() ] ); |
85 | $total += $rows; |
86 | $rows = 0; |
87 | } |
88 | } |
89 | if ( isset( self::$mapping[ $value ] ) ) { |
90 | $optionsToUpdate[$option] = self::$mapping[ $value ]; |
91 | } |
92 | $lastRow = $row; |
93 | } |
94 | |
95 | $total += $this->updateUser( $lastRow, $optionsToUpdate ); |
96 | |
97 | $this->output( "{$total} rows updated.\n" ); |
98 | |
99 | return true; |
100 | } |
101 | |
102 | /** |
103 | * Update one user's preferences |
104 | * |
105 | * @param \stdClass $userRow Row from the user table |
106 | * @param array &$options Associative array of preference => value |
107 | * @return int Number of options updated |
108 | */ |
109 | private function updateUser( $userRow, array &$options ) { |
110 | if ( $userRow->user_id && $options ) { |
111 | $user = User::newFromRow( $userRow ); |
112 | $userOptionsManager = MediaWikiServices::getInstance()->getUserOptionsManager(); |
113 | foreach ( $options as $option => $value ) { |
114 | $userOptionsManager->setOption( $user, $option, $value ); |
115 | } |
116 | $userOptionsManager->saveOptions( $user ); |
117 | } |
118 | $count = count( $options ); |
119 | $options = []; |
120 | return $count; |
121 | } |
122 | |
123 | /** |
124 | * Get the update key name to go in the update log table |
125 | * @return string |
126 | */ |
127 | protected function getUpdateKey() { |
128 | return 'LoginNotify::migratePreferences'; |
129 | } |
130 | } |
131 | |
132 | $maintClass = MigratePreferences::class; |
133 | require_once RUN_MAINTENANCE_IF_MAIN; |