Rewrite reassignEdits script to be more efficient; support optional updates to recent changes table; add reporting and silent modes
This commit is contained in:
parent
cfa7981e34
commit
c29846f281
4 changed files with 173 additions and 96 deletions
|
|
@ -142,7 +142,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
|
|||
* (bug 4737) MediaWiki:Viewcount supports {{PLURAL}} now
|
||||
* Fix bug in wfMsgExt under PHP 5.1.2
|
||||
* (bug 5761) Project talk namespace broken in Xal, Os, Udm and Cv
|
||||
|
||||
* Rewrite reassignEdits script to be more efficient; support optional updates to
|
||||
recent changes table
|
||||
|
||||
== Compatibility ==
|
||||
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Support functions for the reassignEdits script
|
||||
*
|
||||
* @package MediaWiki
|
||||
* @subpackage Maintenance
|
||||
* @author Rob Church <robchur@gmail.com>
|
||||
*/
|
||||
|
||||
function ReassignEdits( $from, $to ) {
|
||||
|
||||
# This stuff needs to come off the master, wrapped in a transaction
|
||||
$dbw =& wfGetDB( DB_MASTER );
|
||||
$dbw->begin();
|
||||
|
||||
$tbl_arc = $dbw->tableName( 'archive' );
|
||||
$tbl_rev = $dbw->tableName( 'revision' );
|
||||
|
||||
$from_txt = $from['text'];
|
||||
$to_id = $to['id'];
|
||||
$to_txt = $to['text'];
|
||||
|
||||
echo( "Searching for current revisions..." );
|
||||
$res = $dbw->query( "SELECT rev_id FROM $tbl_rev WHERE rev_user_text = \"$from_txt\"" );
|
||||
while( $row = $dbw->fetchObject( $res ) ) {
|
||||
$cur[] = $row->rev_id;
|
||||
}
|
||||
$ccount = count( $cur );
|
||||
echo( "found $ccount.\n" );
|
||||
|
||||
echo( "Searching for deleted revisions..." );
|
||||
$res = $dbw->query( "SELECT ar_rev_id FROM $tbl_arc WHERE ar_user_text = \"$from_txt\"" );
|
||||
while( $row = $dbw->fetchObject( $res ) ){
|
||||
$old[] = $row->ar_rev_id;
|
||||
}
|
||||
$ocount = count( $old );
|
||||
echo( "found $ocount.\n" );
|
||||
|
||||
if( $ccount > 0 || $ocount > 0 ) {
|
||||
echo( "Reassigning edits to $to_txt..." );
|
||||
}
|
||||
|
||||
if( $ccount > 0 ) {
|
||||
$set = implode( ', ', $cur );
|
||||
$res = $dbw->query( "UPDATE $tbl_rev SET rev_user = $to_id, rev_user_text = \"$to_txt\" WHERE rev_id IN ( $set )" );
|
||||
}
|
||||
|
||||
if( $ocount > 0 ) {
|
||||
$set = implode( ', ', $old );
|
||||
$res = $dbw->query( "UPDATE $tbl_arc SET ar_user = $to_id, ar_user_text = \"$to_txt\" WHERE ar_rev_id IN ( $set )" );
|
||||
}
|
||||
|
||||
if( $ccount > 0 || $ocount > 0 ) {
|
||||
echo( "done.\n" );
|
||||
}
|
||||
|
||||
$dbw->commit();
|
||||
return( true );
|
||||
|
||||
}
|
||||
|
||||
function GetUserDetails( $spec ) {
|
||||
|
||||
# IP addresses are quick to handle
|
||||
if( User::isIP( $spec ) ) {
|
||||
return( array( 'id' => 0, 'text' => $spec, 'valid' => true ) );
|
||||
}
|
||||
|
||||
# Need to check the user exists and get ID and canonical username
|
||||
$user = User::newFromName( $spec );
|
||||
if( $user->getID() ) {
|
||||
# We have them
|
||||
return( array( 'id' => $user->getID(), 'text' => $user->getName(), 'valid' => true ) );
|
||||
} else {
|
||||
# No such user
|
||||
return( array( 'id' => 0, 'text' => $spec, 'valid' => false ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
144
maintenance/reassignEdits.inc.php
Normal file
144
maintenance/reassignEdits.inc.php
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Support functions for the reassignEdits script
|
||||
*
|
||||
* @package MediaWiki
|
||||
* @subpackage Maintenance
|
||||
* @author Rob Church <robchur@gmail.com>
|
||||
* @licence GNU General Public Licence 2.0 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reassign edits from one user to another
|
||||
*
|
||||
* @param $from User to take edits from
|
||||
* @param $to User to assign edits to
|
||||
* @param $rc Update the recent changes table
|
||||
* @param $report Don't change things; just echo numbers
|
||||
* @return integer Number of entries changed, or that would be changed
|
||||
*/
|
||||
function reassignEdits( &$from, &$to, $rc = false, $report = false ) {
|
||||
$dbw =& wfGetDB( DB_MASTER );
|
||||
$dbw->immediateBegin();
|
||||
$fname = 'reassignEdits';
|
||||
|
||||
# Count things
|
||||
out( "Checking current edits..." );
|
||||
$res = $dbw->select( 'revision', 'COUNT(*) AS count', userConditions( $from, 'rev_user', 'rev_user_text' ), $fname );
|
||||
$row = $dbw->fetchObject( $res );
|
||||
$cur = $row->count;
|
||||
out( "found {$cur}.\n" );
|
||||
|
||||
out( "Checking deleted edits..." );
|
||||
$res = $dbw->select( 'archive', 'COUNT(*) AS count', userConditions( $from, 'ar_user', 'ar_user_text' ), $fname );
|
||||
$row = $dbw->fetchObject( $res );
|
||||
$del = $row->count;
|
||||
out( "found {$del}.\n" );
|
||||
|
||||
# Don't count recent changes if we're not supposed to
|
||||
if( $rc ) {
|
||||
out( "Checking recent changes..." );
|
||||
$res = $dbw->select( 'recentchanges', 'COUNT(*) AS count', userConditions( $from, 'rc_user', 'rc_user_text' ), $fname );
|
||||
$row = $dbw->fetchObject( $res );
|
||||
$rec = $row->count;
|
||||
out( "found {$rec}.\n" );
|
||||
} else {
|
||||
$rec = 0;
|
||||
}
|
||||
|
||||
$total = $cur + $del + $rec;
|
||||
out( "\nTotal entries to change: {$total}\n" );
|
||||
|
||||
if( !$report ) {
|
||||
if( $total ) {
|
||||
# Reassign edits
|
||||
out( "\nReassigning current edits..." );
|
||||
$res = $dbw->update( 'revision', userSpecification( $to, 'rev_user', 'rev_user_text' ), userConditions( $from, 'rev_user', 'rev_user_text' ), $fname );
|
||||
out( "done.\nReassigning deleted edits..." );
|
||||
$res = $dbw->update( 'archive', userSpecification( $to, 'ar_user', 'ar_user_text' ), userConditions( $from, 'ar_user', 'ar_user_text' ), $fname );
|
||||
out( "done.\n" );
|
||||
# Update recent changes if required
|
||||
if( $rc ) {
|
||||
out( "Updating recent changes..." );
|
||||
$res = $dbw->update( 'recentchanges', userSpecification( $to, 'rc_user', 'rc_user_text' ), userConditions( $from, 'rc_user', 'rc_user_text' ), $fname );
|
||||
out( "done.\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$dbw->immediateCommit();
|
||||
return (int)$total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the most efficient set of user conditions
|
||||
* i.e. a user => id mapping, or a user_text => text mapping
|
||||
*
|
||||
* @param $user User for the condition
|
||||
* @param $idfield Field name containing the identifier
|
||||
* @param $utfield Field name containing the user text
|
||||
* @return array
|
||||
*/
|
||||
function userConditions( &$user, $idfield, $utfield ) {
|
||||
return $user->getId() ? array( $idfield => $user->getID() ) : array( $utfield => $user->getName() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return user specifications
|
||||
* i.e. user => id, user_text => text
|
||||
*
|
||||
* @param $user User for the spec
|
||||
* @param $idfield Field name containing the identifier
|
||||
* @param $utfield Field name containing the user text
|
||||
* @return array
|
||||
*/
|
||||
function userSpecification( &$user, $idfield, $utfield ) {
|
||||
return array( $idfield => $user->getId(), $utfield => $user->getName() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo output if $wgSilent is off
|
||||
*
|
||||
* @param $output Output to echo
|
||||
* @return bool True if the output was echoed
|
||||
*/
|
||||
function out( $output ) {
|
||||
global $wgSilent;
|
||||
if( !$wgSilent ) {
|
||||
echo( $output );
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutator for $wgSilent
|
||||
*
|
||||
* @param $silent Switch on $wgSilent
|
||||
*/
|
||||
function silent( $silent = true ) {
|
||||
global $wgSilent;
|
||||
$wgSilent = $silent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the user object
|
||||
*
|
||||
* @param $username Username or IP address
|
||||
* @return User
|
||||
*/
|
||||
function initialiseUser( $username ) {
|
||||
if( User::isIP( $username ) ) {
|
||||
$user = new User();
|
||||
$user->setId( 0 );
|
||||
$user->setName( $username );
|
||||
} else {
|
||||
$user = User::newFromName( $username );
|
||||
}
|
||||
$user->loadFromDatabase();
|
||||
return $user;
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -6,26 +6,38 @@
|
|||
* @package MediaWiki
|
||||
* @subpackage Maintenance
|
||||
* @author Rob Church <robchur@gmail.com>
|
||||
* @licence GNU General Public Licence 2.0 or later
|
||||
*/
|
||||
|
||||
$options = array( 'force' );
|
||||
$options = array( 'force', 'norc', 'quiet', 'report' );
|
||||
require_once( 'commandLine.inc' );
|
||||
require_once( 'reassignEdits.inc' );
|
||||
require_once( 'reassignEdits.inc.php' );
|
||||
|
||||
echo( "Reassign Edits\n\n" );
|
||||
# Set silent mode; --report overrides --quiet
|
||||
if( !@$options['report'] && @$options['quiet'] )
|
||||
setSilent();
|
||||
|
||||
out( "Reassign Edits\n\n" );
|
||||
|
||||
if( @$args[0] && @$args[1] ) {
|
||||
|
||||
$from = GetUserDetails( $args[0] );
|
||||
$to = GetUserDetails( $args[1] );
|
||||
$tor = $args[1];
|
||||
# Set up the users involved
|
||||
$from =& initialiseUser( $args[0] );
|
||||
$to =& initialiseUser( $args[1] );
|
||||
|
||||
if( $to['valid'] || @$options['force'] ) {
|
||||
ReassignEdits( $from, $to );
|
||||
# If the target doesn't exist, and --force is not set, stop here
|
||||
if( $to->getId() || @$options['force'] ) {
|
||||
# Reassign the edits
|
||||
$report = @$options['report'];
|
||||
$count = reassignEdits( $from, $to, !@$options['norc'], $report );
|
||||
# If reporting, and there were items, advise the user to run without --report
|
||||
if( $report )
|
||||
out( "Run the script again without --report to update.\n" );
|
||||
} else {
|
||||
echo( "User \"$tor\" not found.\n" );
|
||||
$ton = $to->getName();
|
||||
echo( "User '{$ton}' not found.\n" );
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
ShowUsage();
|
||||
}
|
||||
|
|
@ -33,10 +45,13 @@ if( @$args[0] && @$args[1] ) {
|
|||
/** Show script usage information */
|
||||
function ShowUsage() {
|
||||
echo( "Reassign edits from one user to another.\n\n" );
|
||||
echo( "Usage: php reassignEdits.php <from> <to> [--force]\n\n" );
|
||||
echo( "Usage: php reassignEdits.php [--force|--quiet|--norc|--report] <from> <to>\n\n" );
|
||||
echo( " <from> : Name of the user to assign edits from\n" );
|
||||
echo( " <to> : Name of the user to assign edits to\n" );
|
||||
echo( " --force : Reassign even if the target user doesn't exist\n\n" );
|
||||
echo( " --force : Reassign even if the target user doesn't exist\n" );
|
||||
echo( " --quiet : Don't print status information (except for errors)\n" );
|
||||
echo( " --norc : Don't update the recent changes table\n" );
|
||||
echo( " --report : Print out details of what would be changed, but don't update it\n\n" );
|
||||
}
|
||||
|
||||
?>
|
||||
Loading…
Reference in a new issue