Index: trunk/extensions/UserMerge/UserMerge_body.php |
— | — | @@ -3,15 +3,15 @@ |
4 | 4 | * \brief Contains code for the UserMerge Class (extends SpecialPage). |
5 | 5 | */ |
6 | 6 | |
7 | | -///Special page class for the User Merge and Delete extension |
8 | 7 | /** |
9 | | - * Special page that allows sysops to merge references from one |
10 | | - * user to another user - also supports deleting users following |
11 | | - * merge. |
| 8 | + * Special page class for the User Merge and Delete extension |
| 9 | + * allows sysops to merge references from one user to another user. |
| 10 | + * It also supports deleting users following merge. |
12 | 11 | * |
13 | 12 | * @ingroup Extensions |
14 | 13 | * @author Tim Laqua <t.laqua@gmail.com> |
15 | 14 | */ |
| 15 | + |
16 | 16 | class UserMerge extends SpecialPage { |
17 | 17 | function __construct() { |
18 | 18 | parent::__construct( 'UserMerge', 'usermerge' ); |
— | — | @@ -155,16 +155,19 @@ |
156 | 156 | $wgOut->addHTML( "<span style=\"color: red;\">" . wfMsg( 'usermerge-badtoken' ) . "</span><br />\n" ); |
157 | 157 | } else { |
158 | 158 | //good editToken |
| 159 | + $this->mergeEditcount( $newuserID,$olduserID ); |
159 | 160 | $this->mergeUser( $objNewUser, $newuser_text, $newuserID, $objOldUser, $olduser_text, $olduserID ); |
160 | 161 | if ( $wgRequest->getText( 'deleteuser' ) ) { |
| 162 | + $this->movePages( $newuser_text, $olduser_text ); |
161 | 163 | $this->deleteUser( $objOldUser, $olduserID, $olduser_text); |
162 | 164 | } |
163 | 165 | } |
164 | 166 | } |
165 | 167 | } |
166 | 168 | |
167 | | - ///Function to delete users following a successful mergeUser call |
168 | 169 | /** |
| 170 | + * Function to delete users following a successful mergeUser call |
| 171 | + * |
169 | 172 | * Removes user entries from the user table and the user_groups table |
170 | 173 | * |
171 | 174 | * @param $olduserID int ID of user to delete |
— | — | @@ -193,8 +196,10 @@ |
194 | 197 | return true; |
195 | 198 | } |
196 | 199 | |
197 | | - ///Function to merge database references from one user to another user |
| 200 | + |
198 | 201 | /** |
| 202 | + * Function to merge database references from one user to another user |
| 203 | + * |
199 | 204 | * Merges database references from one user ID or username to another user ID or username |
200 | 205 | * to preserve referential integrity. |
201 | 206 | * |
— | — | @@ -255,4 +260,153 @@ |
256 | 261 | |
257 | 262 | return true; |
258 | 263 | } |
| 264 | + |
| 265 | + ///Function to add edit count |
| 266 | + /** |
| 267 | + * Adds edit count of both users |
| 268 | + * |
| 269 | + * @param $newuserID int ID of user to merge references TO |
| 270 | + * @param $olduserID int ID of user to remove references FROM |
| 271 | + * |
| 272 | + * @return Always returns true - throws exceptions on failure. |
| 273 | + * |
| 274 | + * @author Matthew April <Matthew.April@tbs-sct.gc.ca> |
| 275 | + */ |
| 276 | + private function mergeEditcount( $newuserID, $olduserID ) { |
| 277 | + global $wgOut; |
| 278 | + |
| 279 | + $dbw =& wfGetDB( DB_MASTER ); |
| 280 | + |
| 281 | + # old user edit count |
| 282 | + $result = $dbw->select( 'user', array('user_editcount'), 'user_id ='.$olduserID ); |
| 283 | + $row = $dbw->fetchRow($result); |
| 284 | + $oldEdits = $row[0]; |
| 285 | + |
| 286 | + # new user edit count |
| 287 | + $result = $dbw->select( 'user', array('user_editcount'), 'user_id ='.$newuserID ); |
| 288 | + $row = $dbw->fetchRow($result); |
| 289 | + $newEdits = $row[0]; |
| 290 | + |
| 291 | + # add edits |
| 292 | + $totalEdits = $oldEdits + $newEdits; |
| 293 | + |
| 294 | + # don't run querys if neither user has any edits |
| 295 | + if( $totalEdits > 0 ) { |
| 296 | + # update new user with total edits |
| 297 | + $dbw->update( 'user', array('user_editcount' => $totalEdits), array('user_id' => $newuserID) ); |
| 298 | + |
| 299 | + #clear old users edits |
| 300 | + $dbw->update( 'user', array('user_editcount' => 0), array('user_id' => $olduserID) ); |
| 301 | + } |
| 302 | + |
| 303 | + $wgOut->addHTML(wfMsgForContent('usermerge-editcount-success', $olduserID, $newuserID) . "<br />\n"); |
| 304 | + |
| 305 | + return true; |
| 306 | + } |
| 307 | + |
| 308 | + |
| 309 | + /** |
| 310 | + * Function to merge user pages |
| 311 | + * |
| 312 | + * Deletes all pages when merging to Anon |
| 313 | + * Moves user page when the target user page does not exist or is empty |
| 314 | + * Deletes redirect if nothing links to old page |
| 315 | + * Deletes the old user page when the target user page exists |
| 316 | + * |
| 317 | + * @param $newuser_text string Username to merge pages TO |
| 318 | + * @param $olduser_text string Username of user to remove pages FROM |
| 319 | + * |
| 320 | + * @return returns true on completion |
| 321 | + * |
| 322 | + * @author Matthew April <Matthew.April@tbs-sct.gc.ca> |
| 323 | + */ |
| 324 | + private function movePages( $newuser_text, $olduser_text ) { |
| 325 | + |
| 326 | + global $wgOut, $wgTitle, $wgContLang, $wgUser; |
| 327 | + |
| 328 | + $oldusername = trim( str_replace( '_', ' ', $olduser_text ) ); |
| 329 | + $oldusername = Title::makeTitle( NS_USER, $oldusername ); |
| 330 | + $newusername = Title::makeTitleSafe( NS_USER, $wgContLang->ucfirst( $newuser_text ) ); |
| 331 | + |
| 332 | + # select all user pages and sub-pages |
| 333 | + $dbr = wfGetDB( DB_SLAVE ); |
| 334 | + $oldkey = $oldusername->getDBkey(); |
| 335 | + $pages = $dbr->select( |
| 336 | + 'page', |
| 337 | + array( 'page_namespace', 'page_title' ), |
| 338 | + array( |
| 339 | + 'page_namespace IN (' . NS_USER . ',' . NS_USER_TALK . ')', |
| 340 | + '(page_title LIKE ' . |
| 341 | + $dbr->addQuotes( $dbr->escapeLike( $oldusername->getDBkey() ) . '/%' ) . |
| 342 | + ' OR page_title = ' . $dbr->addQuotes( $oldusername->getDBkey() ) . ')' |
| 343 | + ) |
| 344 | + ); |
| 345 | + |
| 346 | + $output = ''; |
| 347 | + $skin =& $wgUser->getSkin(); |
| 348 | + while ( $row = $dbr->fetchObject( $pages ) ) { |
| 349 | + $oldPage = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); |
| 350 | + $newPage = Title::makeTitleSafe( $row->page_namespace, |
| 351 | + preg_replace( '!^[^/]+!', $newusername->getDBkey(), $row->page_title ) ); |
| 352 | + |
| 353 | + |
| 354 | + if( $newuser_text == "Anonymous" ) { # delete ALL old pages |
| 355 | + |
| 356 | + if( $oldPage->exists() ) { |
| 357 | + $oldPageArticle = new Article($oldPage); |
| 358 | + $oldPageArticle->doDeleteArticle( wfMsgHtml('usermerge-autopagedelete') ); |
| 359 | + |
| 360 | + $oldLink = $skin->makeKnownLinkObj( $oldPage ); |
| 361 | + $output .= '<li class="mw-renameuser-pe">' . wfMsgHtml( 'usermerge-page-deleted', $oldLink ) . '</li>'; |
| 362 | + } |
| 363 | + |
| 364 | + } elseif( $newPage->exists() && !$oldPage->isValidMoveTarget( $newPage ) && $newPage->getLength() > 0) { # delete old pages that can't be moved |
| 365 | + |
| 366 | + $oldPageArticle = new Article($oldPage); |
| 367 | + $oldPageArticle->doDeleteArticle( wfMsgHtml('usermerge-autopagedelete') ); |
| 368 | + |
| 369 | + $link = $skin->makeKnownLinkObj( $oldPage ); |
| 370 | + $output .= '<li class="mw-renameuser-pe">' . wfMsgHtml( 'usermerge-page-deleted', $link ) . '</li>'; |
| 371 | + |
| 372 | + } else { # move content to new page |
| 373 | + |
| 374 | + # delete target page if it exists and is blank |
| 375 | + if( $newPage->exists() ) { |
| 376 | + $newPageArticle = new Article($newPage); |
| 377 | + $newPageArticle->doDeleteArticle('usermerge-autopagedelete'); |
| 378 | + } |
| 379 | + |
| 380 | + # move to target location |
| 381 | + $success = $oldPage->moveTo( $newPage, false, wfMsgForContent( 'usermerge-move-log', |
| 382 | + $oldusername->getText(), $newusername->getText() ) ); |
| 383 | + if( $success === true ) { |
| 384 | + $oldLink = $skin->makeKnownLinkObj( $oldPage, '', 'redirect=no' ); |
| 385 | + $newLink = $skin->makeKnownLinkObj( $newPage ); |
| 386 | + $output .= '<li class="mw-renameuser-pm">' . wfMsgHtml( 'usermerge-page-moved', $oldLink, $newLink ) . '</li>'; |
| 387 | + } else { |
| 388 | + $oldLink = $skin->makeKnownLinkObj( $oldPage ); |
| 389 | + $newLink = $skin->makeLinkObj( $newPage ); |
| 390 | + $output .= '<li class="mw-renameuser-pu">' . wfMsgHtml( 'usermerge-page-unmoved', $oldLink, $newLink ) . '</li>'; |
| 391 | + } |
| 392 | + |
| 393 | + # check if any pages link here |
| 394 | + $res = $dbr->select( 'pagelinks', |
| 395 | + 'pl_title' , |
| 396 | + array( 'pl_title' => $olduser_text ), |
| 397 | + __METHOD__ |
| 398 | + ); |
| 399 | + if( !$dbr->numRows( $res ) ) { |
| 400 | + # nothing links here, so delete unmoved page/redirect |
| 401 | + $oldPageArticle = new Article($oldPage); |
| 402 | + $oldPageArticle->doDeleteArticle( wfMsgHtml('usermerge-autopagedelete') ); |
| 403 | + } |
| 404 | + |
| 405 | + } |
| 406 | + } |
| 407 | + |
| 408 | + if( $output ) |
| 409 | + $wgOut->addHTML( '<ul>' . $output . '</ul>' ); |
| 410 | + |
| 411 | + return true; |
| 412 | + } |
259 | 413 | } |
Index: trunk/extensions/UserMerge/UserMerge.i18n.php |
— | — | @@ -33,6 +33,13 @@ |
34 | 34 | 'usermerge-unmergable' => 'Unable to merge from user - ID or name has been defined as unmergable.', |
35 | 35 | 'usermerge-protectedgroup' => 'Unable to merge from user - user is in a protected group.', |
36 | 36 | 'right-usermerge' => 'Merge users', |
| 37 | + 'usermerge-editcount' => 'Add edit count?', |
| 38 | + 'usermerge-editcount-success' => 'Adding edit count of ($1 and $2)', |
| 39 | + 'usermerge-autopagedelete' => 'Automatically deleted when merging users', |
| 40 | + 'usermerge-page-unmoved' => 'The page $1 could not be moved to $2.', |
| 41 | + 'usermerge-page-moved' => 'The page $1 has been moved to $2.', |
| 42 | + 'usermerge-move-log' => 'Automatically moved page while merging the user "[[User:$1|$1]]" to "[[User:$2|$2]]"', |
| 43 | + 'usermerge-page-deleted' => 'Deleted page $1', |
37 | 44 | ); |
38 | 45 | |
39 | 46 | /** Message documentation (Message documentation) |
Index: trunk/extensions/UserMerge/UserMerge.php |
— | — | @@ -3,6 +3,27 @@ |
4 | 4 | * \brief Contains setup code for the User Merge and Delete Extension. |
5 | 5 | */ |
6 | 6 | |
| 7 | +/* |
| 8 | + * UserMerge Extension for MediaWiki |
| 9 | + * |
| 10 | + * Copyright (C) PediaPress GmbH |
| 11 | + * |
| 12 | + * This program is free software; you can redistribute it and/or modify |
| 13 | + * it under the terms of the GNU General Public License as published by |
| 14 | + * the Free Software Foundation; either version 2 of the License, or |
| 15 | + * (at your option) any later version. |
| 16 | + * |
| 17 | + * This program is distributed in the hope that it will be useful, |
| 18 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 20 | + * GNU General Public License for more details. |
| 21 | + * |
| 22 | + * You should have received a copy of the GNU General Public License along |
| 23 | + * with this program; if not, write to the Free Software Foundation, Inc., |
| 24 | + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 25 | + * http://www.gnu.org/copyleft/gpl.html |
| 26 | + */ |
| 27 | + |
7 | 28 | # Not a valid entry point, skip unless MEDIAWIKI is defined |
8 | 29 | if (!defined('MEDIAWIKI')) { |
9 | 30 | echo "User Merge and Delete extension"; |
— | — | @@ -13,9 +34,9 @@ |
14 | 35 | 'path' => __FILE__, |
15 | 36 | 'name' => 'User Merge and Delete', |
16 | 37 | 'url' => 'http://www.mediawiki.org/wiki/Extension:User_Merge_and_Delete', |
17 | | - 'author' => array( 'Tim Laqua', 'Thomas Gries' ), |
| 38 | + 'author' => array( 'Tim Laqua', 'Thomas Gries', 'Matthew April' ), |
18 | 39 | 'descriptionmsg' => 'usermerge-desc', |
19 | | - 'version' => '1.6.21' |
| 40 | + 'version' => '1.6.3' |
20 | 41 | ); |
21 | 42 | |
22 | 43 | $wgAvailableRights[] = 'usermerge'; |