From b9ecc8c04c5a6a4a1ade2b245e63c4f546f614ff Mon Sep 17 00:00:00 2001 From: David Barratt Date: Wed, 23 Aug 2017 10:38:58 -0400 Subject: [PATCH] Use User Ids instead of User Names for Echo Mute The echo mute list uses user names which are not stable. User ids should be used instead. Bug: T173475 Change-Id: I947bcf37a8f85aaa105776d368dbd0ab76823aeb --- Hooks.php | 25 +++++++++ extension.json | 3 +- includes/ContainmentSet.php | 8 +-- maintenance/updatePerUserBlacklist.php | 95 ++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 maintenance/updatePerUserBlacklist.php diff --git a/Hooks.php b/Hooks.php index 8e3db35d..84cb2f2b 100644 --- a/Hooks.php +++ b/Hooks.php @@ -490,10 +490,14 @@ class EchoHooks { } if ( $wgEchoPerUserBlacklist ) { + $lookup = CentralIdLookup::factory(); + $ids = $user->getOption( 'echo-notifications-blacklist', [] ); + $names = $ids ? $lookup->lookupCentralIds( array_flip( $ids ), $user ) : []; $preferences['echo-notifications-blacklist'] = [ 'type' => 'usersmultiselect', 'label-message' => 'echo-pref-notifications-blacklist', 'section' => 'echo/blocknotificationslist', + 'default' => implode( "\n", array_values( $names ) ) ]; } @@ -1252,6 +1256,10 @@ class EchoHooks { $options['echo-subscriptions-email-edit-user-talk'] = $options['enotifusertalkpages']; } + if ( isset( $options['echo-notifications-blacklist'] ) ) { + $options['echo-notifications-blacklist'] = array_map( 'intval', explode( "\n", $options['echo-notifications-blacklist'] ) ); + } + return true; } @@ -1270,6 +1278,23 @@ class EchoHooks { unset( $options['echo-subscriptions-email-edit-user-talk'] ); } + // Convert the usernames to ids. + if ( isset( $options['echo-notifications-blacklist'] ) ) { + if ( $options['echo-notifications-blacklist'] ) { + $lookup = CentralIdLookup::factory(); + $names = $options['echo-notifications-blacklist']; + if ( is_string( $names ) ) { + $names = explode( "\n", $names ); + } + $ids = $lookup->lookupUserNames( array_flip( $names ), $user ); + $options['echo-notifications-blacklist'] = implode( "\n", array_values( $ids ) ); + } + else { + // If the blacklist is empty, set it to null rather than an empty string. + $options['echo-notifications-blacklist'] = null; + } + } + return true; } diff --git a/extension.json b/extension.json index 39606dbc..2ae045fb 100644 --- a/extension.json +++ b/extension.json @@ -1019,6 +1019,7 @@ "SpecialNotificationsMarkRead": "includes/special/SpecialNotificationsMarkRead.php", "SuppressionMaintenanceTest": "tests/phpunit/maintenance/SupressionMaintenanceTest.php", "TestDiscussionParser": "maintenance/testDiscussionParser.php", - "UpdateEchoSchemaForSuppression": "maintenance/updateEchoSchemaForSuppression.php" + "UpdateEchoSchemaForSuppression": "maintenance/updateEchoSchemaForSuppression.php", + "EchoUpdatePerUserBlocklist": "maintenance/updatePerUserBlocklist.php" } } diff --git a/includes/ContainmentSet.php b/includes/ContainmentSet.php index 4b6ce1f8..d5cfff5f 100644 --- a/includes/ContainmentSet.php +++ b/includes/ContainmentSet.php @@ -71,12 +71,12 @@ class EchoContainmentSet { * @param string $preferenceName */ public function addFromUserOption( $preferenceName ) { - $preference = $this->recipient->getOption( $preferenceName ); + $preference = $this->recipient->getOption( $preferenceName, [] ); if ( $preference ) { - $items = explode( "\n", $preference ); - - $this->addArray( $items ); + $lookup = CentralIdLookup::factory(); + $names = $lookup->lookupCentralIds( array_flip( $preference ), $this->recipient ); + $this->addArray( array_values( $names ) ); } } diff --git a/maintenance/updatePerUserBlacklist.php b/maintenance/updatePerUserBlacklist.php new file mode 100644 index 00000000..a7b4d655 --- /dev/null +++ b/maintenance/updatePerUserBlacklist.php @@ -0,0 +1,95 @@ +mDescription = "Update echo-notifications-blacklist User Preference from Usernames to Ids"; + $this->setBatchSize( 100 ); + $this->requireExtension( 'Echo' ); + } + + public function getUpdateKey() { + return __CLASS__; + } + + public function doDBUpdates() { + $dbFactory = MWEchoDbFactory::newFromDefault(); + $dbw = $dbFactory->getEchoDb( DB_MASTER ); + $dbr = $dbFactory->getEchoDb( DB_SLAVE ); + $iterator = new BatchRowIterator( + $dbr, + 'user_properties', + [ 'up_user', 'up_property' ], + $this->mBatchSize + ); + $iterator->setFetchColumns( [ + 'up_user', + 'up_value' + ] ); + $iterator->addConditions( [ + 'up_property' => 'echo-notifications-blacklist' + ] ); + + $this->output( "Updating Echo Notification Blacklist...\n" ); + + $lookup = CentralIdLookup::factory(); + $processed = 0; + foreach ( $iterator as $batch ) { + foreach ( $batch as $row ) { + + if ( !$row->up_value ) { + continue; + } + + $value = explode( "\n", $row->up_value ); + $names = array_filter( $value, function( $item ) { + return !is_numeric( $item ); + } ); + + // If all of the values are numeric then the user has already been + // converted. + if ( !$names ) { + continue; + } + + $user = User::newFromId( $row->up_user ); + $ids = $lookup->lookupUserNames( array_flip( $names ), $user ); + + $dbw->update( + 'user_properties', + [ + 'up_value' => implode( "\n", array_values( $ids ) ), + ], + [ + 'up_user' => $row->up_user, + 'up_property' => 'echo-notifications-blacklist', + ] + ); + $processed += $dbw->affectedRows(); + $dbFactory->waitForSlaves(); + } + + $this->output( "Updated $processed Users\n" ); + } + + return true; + } +} + +$maintClass = 'EchoUpdatePerUserBlocklist'; +require_once RUN_MAINTENANCE_IF_MAIN; -- 2.13.1