MediaWiki
REL1_22
|
00001 <?php 00024 require_once __DIR__ . '/Maintenance.php'; 00025 00031 class MigrateUserGroup extends Maintenance { 00032 public function __construct() { 00033 parent::__construct(); 00034 $this->mDescription = "Re-assign users from an old group to a new one"; 00035 $this->addArg( 'oldgroup', 'Old user group key', true ); 00036 $this->addArg( 'newgroup', 'New user group key', true ); 00037 $this->setBatchSize( 200 ); 00038 } 00039 00040 public function execute() { 00041 $count = 0; 00042 $oldGroup = $this->getArg( 0 ); 00043 $newGroup = $this->getArg( 1 ); 00044 $dbw = wfGetDB( DB_MASTER ); 00045 $start = $dbw->selectField( 'user_groups', 'MIN(ug_user)', 00046 array( 'ug_group' => $oldGroup ), __FUNCTION__ ); 00047 $end = $dbw->selectField( 'user_groups', 'MAX(ug_user)', 00048 array( 'ug_group' => $oldGroup ), __FUNCTION__ ); 00049 if ( $start === null ) { 00050 $this->error( "Nothing to do - no users in the '$oldGroup' group", true ); 00051 } 00052 # Do remaining chunk 00053 $end += $this->mBatchSize - 1; 00054 $blockStart = $start; 00055 $blockEnd = $start + $this->mBatchSize - 1; 00056 // Migrate users over in batches... 00057 while ( $blockEnd <= $end ) { 00058 $affected = 0; 00059 $this->output( "Doing users $blockStart to $blockEnd\n" ); 00060 00061 $dbw->begin( __METHOD__ ); 00062 $dbw->update( 'user_groups', 00063 array( 'ug_group' => $newGroup ), 00064 array( 'ug_group' => $oldGroup, 00065 "ug_user BETWEEN $blockStart AND $blockEnd" ), 00066 __METHOD__, 00067 array( 'IGNORE' ) 00068 ); 00069 $affected += $dbw->affectedRows(); 00070 // Delete rows that the UPDATE operation above had to ignore. 00071 // This happens when a user is in both the old and new group. 00072 // Updating the row for the old group membership failed since 00073 // user/group is UNIQUE. 00074 $dbw->delete( 'user_groups', 00075 array( 'ug_group' => $oldGroup, 00076 "ug_user BETWEEN $blockStart AND $blockEnd" ), 00077 __METHOD__ 00078 ); 00079 $affected += $dbw->affectedRows(); 00080 $dbw->commit( __METHOD__ ); 00081 00082 // Clear cache for the affected users (bug 40340) 00083 if ( $affected > 0 ) { 00084 // XXX: This also invalidates cache of unaffected users that 00085 // were in the new group and not in the group. 00086 $res = $dbw->select( 'user_groups', 'ug_user', 00087 array( 'ug_group' => $newGroup, 00088 "ug_user BETWEEN $blockStart AND $blockEnd" ), 00089 __METHOD__ 00090 ); 00091 if ( $res !== false ) { 00092 foreach ( $res as $row ) { 00093 $user = User::newFromId( $row->ug_user ); 00094 $user->invalidateCache(); 00095 } 00096 } 00097 } 00098 00099 $count += $affected; 00100 $blockStart += $this->mBatchSize; 00101 $blockEnd += $this->mBatchSize; 00102 wfWaitForSlaves(); 00103 } 00104 $this->output( "Done! $count users in group '$oldGroup' are now in '$newGroup' instead.\n" ); 00105 } 00106 } 00107 00108 $maintClass = "MigrateUserGroup"; 00109 require_once RUN_MAINTENANCE_IF_MAIN;