MediaWiki  REL1_21
migrateUserGroup.php
Go to the documentation of this file.
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 );