* (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 ==
+++ /dev/null
-<?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 ) );
- }
-
-}
-
-
-?>
--- /dev/null
+<?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;
+}
+
+?>
\ No newline at end of file
* @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();
}
/** 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" );
}
?>
\ No newline at end of file