]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - maintenance/migrateUserGroup.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / maintenance / migrateUserGroup.php
index c41632086f237b9237758f43d7c4ca705f24fc01..597a876df92e90519843f55ebd6bcedf575fe51d 100644 (file)
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  * http://www.gnu.org/copyleft/gpl.html
  *
+ * @file
  * @ingroup Maintenance
  */
 
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once __DIR__ . '/Maintenance.php';
 
+/**
+ * Maintenance script that re-assigns users from an old group to a new one.
+ *
+ * @ingroup Maintenance
+ */
 class MigrateUserGroup extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Re-assign users from an old group to a new one";
+               $this->addDescription( 'Re-assign users from an old group to a new one' );
                $this->addArg( 'oldgroup', 'Old user group key', true );
                $this->addArg( 'newgroup', 'New user group key', true );
                $this->setBatchSize( 200 );
@@ -35,11 +41,11 @@ class MigrateUserGroup extends Maintenance {
                $count = 0;
                $oldGroup = $this->getArg( 0 );
                $newGroup = $this->getArg( 1 );
-               $dbw = wfGetDB( DB_MASTER );
+               $dbw = $this->getDB( DB_MASTER );
                $start = $dbw->selectField( 'user_groups', 'MIN(ug_user)',
-                       array( 'ug_group' => $oldGroup ), __FUNCTION__ );
+                       [ 'ug_group' => $oldGroup ], __FUNCTION__ );
                $end = $dbw->selectField( 'user_groups', 'MAX(ug_user)',
-                       array( 'ug_group' => $oldGroup ), __FUNCTION__ );
+                       [ 'ug_group' => $oldGroup ], __FUNCTION__ );
                if ( $start === null ) {
                        $this->error( "Nothing to do - no users in the '$oldGroup' group", true );
                }
@@ -49,22 +55,55 @@ class MigrateUserGroup extends Maintenance {
                $blockEnd = $start + $this->mBatchSize - 1;
                // Migrate users over in batches...
                while ( $blockEnd <= $end ) {
+                       $affected = 0;
                        $this->output( "Doing users $blockStart to $blockEnd\n" );
-                       $dbw->begin();
+
+                       $this->beginTransaction( $dbw, __METHOD__ );
                        $dbw->update( 'user_groups',
-                               array( 'ug_group' => $newGroup ),
-                               array( 'ug_group' => $oldGroup,
-                                       "ug_user BETWEEN $blockStart AND $blockEnd" )
+                               [ 'ug_group' => $newGroup ],
+                               [ 'ug_group' => $oldGroup,
+                                       "ug_user BETWEEN $blockStart AND $blockEnd" ],
+                               __METHOD__,
+                               [ 'IGNORE' ]
+                       );
+                       $affected += $dbw->affectedRows();
+                       // Delete rows that the UPDATE operation above had to ignore.
+                       // This happens when a user is in both the old and new group.
+                       // Updating the row for the old group membership failed since
+                       // user/group is UNIQUE.
+                       $dbw->delete( 'user_groups',
+                               [ 'ug_group' => $oldGroup,
+                                       "ug_user BETWEEN $blockStart AND $blockEnd" ],
+                               __METHOD__
                        );
-                       $count += $dbw->affectedRows();
-                       $dbw->commit();
+                       $affected += $dbw->affectedRows();
+                       $this->commitTransaction( $dbw, __METHOD__ );
+
+                       // Clear cache for the affected users (T42340)
+                       if ( $affected > 0 ) {
+                               // XXX: This also invalidates cache of unaffected users that
+                               // were in the new group and not in the group.
+                               $res = $dbw->select( 'user_groups', 'ug_user',
+                                       [ 'ug_group' => $newGroup,
+                                               "ug_user BETWEEN $blockStart AND $blockEnd" ],
+                                       __METHOD__
+                               );
+                               if ( $res !== false ) {
+                                       foreach ( $res as $row ) {
+                                               $user = User::newFromId( $row->ug_user );
+                                               $user->invalidateCache();
+                                       }
+                               }
+                       }
+
+                       $count += $affected;
                        $blockStart += $this->mBatchSize;
                        $blockEnd += $this->mBatchSize;
-                       wfWaitForSlaves( 5 );
+                       wfWaitForSlaves();
                }
-               $this->output( "Done! $count user(s) in group '$oldGroup' are now in '$newGroup' instead.\n" );
+               $this->output( "Done! $count users in group '$oldGroup' are now in '$newGroup' instead.\n" );
        }
 }
 
 $maintClass = "MigrateUserGroup";
-require_once( RUN_MAINTENANCE_IF_MAIN );
+require_once RUN_MAINTENANCE_IF_MAIN;