r37928 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r37927‎ | r37928 | r37929 >
Date:22:44, 22 July 2008
Author:tstarling
Status:old
Tags:
Comment:
* (bug 4578) Automatically fix redirects broken by a page move. Works via the job queue, controllable by a checkbox on Special:Movepage.
* Renamed some excessively short variables in SpecialMovepage.php
* Allow $wgReservedUsernames to be localised using "msg:..." syntax
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/includes/JobQueue.php (modified) (history)
  • /trunk/phase3/includes/User.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialMovepage.php (modified) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/User.php
@@ -497,12 +497,21 @@
498498 */
499499 static function isUsableName( $name ) {
500500 global $wgReservedUsernames;
501 - return
502 - // Must be a valid username, obviously ;)
503 - self::isValidUserName( $name ) &&
 501+ // Must be a valid username, obviously ;)
 502+ if ( !self::isValidUserName( $name ) ) {
 503+ return false;
 504+ }
504505
505 - // Certain names may be reserved for batch processes.
506 - !in_array( $name, $wgReservedUsernames );
 506+ // Certain names may be reserved for batch processes.
 507+ foreach ( $wgReservedUsernames as $reserved ) {
 508+ if ( substr( $reserved, 0, 4 ) == 'msg:' ) {
 509+ $reserved = wfMsgForContent( substr( $reserved, 4 ) );
 510+ }
 511+ if ( $reserved == $name ) {
 512+ return false;
 513+ }
 514+ }
 515+ return true;
507516 }
508517
509518 /**
Index: trunk/phase3/includes/DefaultSettings.php
@@ -1595,6 +1595,7 @@
15961596 'html_cache_update' => 'HTMLCacheUpdateJob', // backwards-compatible
15971597 'sendMail' => 'EmaillingJob',
15981598 'enotifNotify' => 'EnotifNotifyJob',
 1599+ 'fixDoubleRedirect' => 'DoubleRedirectJob',
15991600 );
16001601
16011602 /**
@@ -3078,6 +3079,7 @@
30793080 'Conversion script', // Used for the old Wikipedia software upgrade
30803081 'Maintenance script', // Maintenance scripts which perform editing, image import script
30813082 'Template namespace initialisation script', // Used in 1.2->1.3 upgrade
 3083+ 'msg:double-redirect-fixer', // Automatic double redirect fix
30823084 );
30833085
30843086 /**
Index: trunk/phase3/includes/JobQueue.php
@@ -163,7 +163,10 @@
164164 $job = Job::factory( $row->job_cmd, $title, Job::extractBlob( $row->job_params ), $row->job_id );
165165
166166 // Remove any duplicates it may have later in the queue
 167+ // Deadlock prone section
 168+ $dbw->begin();
167169 $dbw->delete( 'job', $job->insertFields(), __METHOD__ );
 170+ $dbw->commit();
168171
169172 wfProfileOut( __METHOD__ );
170173 return $job;
@@ -213,12 +216,23 @@
214217 * @param $jobs array of Job objects
215218 */
216219 static function batchInsert( $jobs ) {
217 - if( count( $jobs ) ) {
218 - $dbw = wfGetDB( DB_MASTER );
 220+ if( !count( $jobs ) ) {
 221+ return;
 222+ }
 223+ $dbw = wfGetDB( DB_MASTER );
 224+ $rows = array();
 225+ foreach( $jobs as $job ) {
 226+ $rows[] = $job->insertFields();
 227+ if ( count( $rows ) >= 50 ) {
 228+ # Do a small transaction to avoid slave lag
 229+ $dbw->begin();
 230+ $dbw->insert( 'job', $rows, __METHOD__, 'IGNORE' );
 231+ $dbw->commit();
 232+ $rows = array();
 233+ }
 234+ }
 235+ if ( $rows ) {
219236 $dbw->begin();
220 - foreach( $jobs as $job ) {
221 - $rows[] = $job->insertFields();
222 - }
223237 $dbw->insert( 'job', $rows, __METHOD__, 'IGNORE' );
224238 $dbw->commit();
225239 }
@@ -288,6 +302,10 @@
289303 }
290304 }
291305
 306+ protected function setLastError( $error ) {
 307+ $this->error = $error;
 308+ }
 309+
292310 function getLastError() {
293311 return $this->error;
294312 }
Index: trunk/phase3/includes/AutoLoader.php
@@ -43,6 +43,7 @@
4444 '_DiffOp' => 'includes/DifferenceEngine.php',
4545 'DjVuImage' => 'includes/DjVuImage.php',
4646 'DoubleReplacer' => 'includes/StringUtils.php',
 47+ 'DoubleRedirectJob' => 'includes/DoubleRedirectJob.php',
4748 'Dump7ZipOutput' => 'includes/Export.php',
4849 'DumpBZip2Output' => 'includes/Export.php',
4950 'DumpFileOutput' => 'includes/Export.php',
Index: trunk/phase3/includes/specials/SpecialMovepage.php
@@ -17,36 +17,35 @@
1818 }
1919
2020 $target = isset( $par ) ? $par : $wgRequest->getVal( 'target' );
21 - $oldTitle = $wgRequest->getText( 'wpOldTitle', $target );
22 - $newTitle = $wgRequest->getText( 'wpNewTitle' );
 21+ $oldTitleText = $wgRequest->getText( 'wpOldTitle', $target );
 22+ $newTitleText = $wgRequest->getText( 'wpNewTitle' );
2323
24 - # Variables beginning with 'o' for old article 'n' for new article
25 - $ot = Title::newFromText( $oldTitle );
26 - $nt = Title::newFromText( $newTitle );
 24+ $oldTitle = Title::newFromText( $oldTitleText );
 25+ $newTitle = Title::newFromText( $newTitleText );
2726
28 - if( is_null( $ot ) ) {
 27+ if( is_null( $oldTitle ) ) {
2928 $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
3029 return;
3130 }
32 - if( !$ot->exists() ) {
 31+ if( !$oldTitle->exists() ) {
3332 $wgOut->showErrorPage( 'nopagetitle', 'nopagetext' );
3433 return;
3534 }
3635
3736 # Check rights
38 - $permErrors = $ot->getUserPermissionsErrors( 'move', $wgUser );
 37+ $permErrors = $oldTitle->getUserPermissionsErrors( 'move', $wgUser );
3938 if( !empty( $permErrors ) ) {
4039 $wgOut->showPermissionsErrorPage( $permErrors );
4140 return;
4241 }
4342
44 - $f = new MovePageForm( $ot, $nt );
 43+ $form = new MovePageForm( $oldTitle, $newTitle );
4544
4645 if ( 'submit' == $action && $wgRequest->wasPosted()
4746 && $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
48 - $f->doSubmit();
 47+ $form->doSubmit();
4948 } else {
50 - $f->showForm( '' );
 49+ $form->showForm( '' );
5150 }
5251 }
5352
@@ -56,7 +55,7 @@
5756 */
5857 class MovePageForm {
5958 var $oldTitle, $newTitle, $reason; # Text input
60 - var $moveTalk, $deleteAndMove, $moveSubpages;
 59+ var $moveTalk, $deleteAndMove, $moveSubpages, $fixRedirects;
6160
6261 private $watch = false;
6362
@@ -73,17 +72,17 @@
7473 }
7574 $this->moveSubpages = $wgRequest->getBool( 'wpMovesubpages', false );
7675 $this->deleteAndMove = $wgRequest->getBool( 'wpDeleteAndMove' ) && $wgRequest->getBool( 'wpConfirm' );
 76+ $this->fixRedirects = $wgRequest->getBool( 'wpFixRedirects', true );
7777 $this->watch = $wgRequest->getCheck( 'wpWatch' );
7878 }
7979
8080 function showForm( $err, $hookErr = '' ) {
8181 global $wgOut, $wgUser;
8282
83 - $ot = $this->oldTitle;
84 - $sk = $wgUser->getSkin();
 83+ $skin = $wgUser->getSkin();
8584
86 - $oldTitleLink = $sk->makeLinkObj( $ot );
87 - $oldTitle = $ot->getPrefixedText();
 85+ $oldTitleLink = $skin->makeLinkObj( $this->oldTitle );
 86+ $oldTitle = $this->oldTitle->getPrefixedText();
8887
8988 $wgOut->setPagetitle( wfMsg( 'move-page', $oldTitle ) );
9089 $wgOut->setSubtitle( wfMsg( 'move-page-backlink', $oldTitleLink ) );
@@ -99,7 +98,7 @@
10099 # If a title was supplied, probably from the move log revert
101100 # link, check for validity. We can then show some diagnostic
102101 # information and save a click.
103 - $newerr = $ot->isValidMoveOperation( $nt );
 102+ $newerr = $this->oldTitle->isValidMoveOperation( $nt );
104103 if( is_string( $newerr ) ) {
105104 $err = $newerr;
106105 }
@@ -127,9 +126,16 @@
128127 $confirm = false;
129128 }
130129
131 - $oldTalk = $ot->getTalkPage();
132 - $considerTalk = ( !$ot->isTalkPage() && $oldTalk->exists() );
 130+ $oldTalk = $this->oldTitle->getTalkPage();
 131+ $considerTalk = ( !$this->oldTitle->isTalkPage() && $oldTalk->exists() );
133132
 133+ $dbr = wfGetDB( DB_SLAVE );
 134+ $hasRedirects = $dbr->selectField( 'redirect', '1',
 135+ array(
 136+ 'rd_namespace' => $this->oldTitle->getNamespace(),
 137+ 'rd_title' => $this->oldTitle->getDBkey(),
 138+ ) , __METHOD__ );
 139+
134140 if ( $considerTalk ) {
135141 $wgOut->addWikiMsg( 'movepagetalktext' );
136142 }
@@ -190,28 +196,41 @@
191197 );
192198 }
193199
194 - if( ($ot->hasSubpages() || $ot->getTalkPage()->hasSubpages())
195 - && $ot->userCan( 'move-subpages' ) ) {
 200+ if ( $hasRedirects ) {
196201 $wgOut->addHTML( "
197202 <tr>
198203 <td></td>
 204+ <td class='mw-input' >" .
 205+ Xml::checkLabel( wfMsg( 'fix-double-redirects' ), 'wpFixRedirects',
 206+ 'wpFixRedirects', $this->fixRedirects ) .
 207+ "</td>
 208+ </td>"
 209+ );
 210+ }
 211+
 212+ if( ($this->oldTitle->hasSubpages() || $this->oldTitle->getTalkPage()->hasSubpages())
 213+ && $this->oldTitle->userCan( 'move-subpages' ) ) {
 214+ $wgOut->addHTML( "
 215+ <tr>
 216+ <td></td>
199217 <td class=\"mw-input\">" .
200218 Xml::checkLabel( wfMsgHtml(
201 - $ot->hasSubpages()
 219+ $this->oldTitle->hasSubpages()
202220 ? 'move-subpages'
203221 : 'move-talk-subpages'
204222 ),
205223 'wpMovesubpages', 'wpMovesubpages',
206224 # Don't check the box if we only have talk subpages to
207225 # move and we aren't moving the talk page.
208 - $this->moveSubpages && ($ot->hasSubpages() || $this->moveTalk)
 226+ $this->moveSubpages && ($this->oldTitle->hasSubpages() || $this->moveTalk)
209227 ) .
210228 "</td>
211229 </tr>"
212230 );
213231 }
214232
215 - $watchChecked = $this->watch || $wgUser->getBoolOption( 'watchmoves' ) || $ot->userIsWatching();
 233+ $watchChecked = $this->watch || $wgUser->getBoolOption( 'watchmoves' )
 234+ || $this->oldTitle->userIsWatching();
216235 $wgOut->addHTML( "
217236 <tr>
218237 <td></td>
@@ -233,7 +252,7 @@
234253 "\n"
235254 );
236255
237 - $this->showLogFragment( $ot, $wgOut );
 256+ $this->showLogFragment( $this->oldTitle, $wgOut );
238257
239258 }
240259
@@ -277,6 +296,10 @@
278297 return;
279298 }
280299
 300+ if ( $this->fixRedirects ) {
 301+ DoubleRedirectJob::fixRedirects( 'move', $ot, $nt );
 302+ }
 303+
281304 wfRunHooks( 'SpecialMovepageAfterMove', array( &$this , &$ot , &$nt ) ) ;
282305
283306 $wgOut->setPagetitle( wfMsg( 'pagemovedsub' ) );
@@ -358,40 +381,43 @@
359382 continue;
360383 }
361384
362 - $oldPage = Title::newFromRow( $row );
 385+ $oldSubpage = Title::newFromRow( $row );
363386 $newPageName = preg_replace(
364387 '#^'.preg_quote( $ot->getDBKey(), '#' ).'#',
365388 $nt->getDBKey(),
366 - $oldPage->getDBKey()
 389+ $oldSubpage->getDBKey()
367390 );
368 - if( $oldPage->isTalkPage() ) {
 391+ if( $oldSubpage->isTalkPage() ) {
369392 $newNs = $nt->getTalkPage()->getNamespace();
370393 } else {
371394 $newNs = $nt->getSubjectPage()->getNamespace();
372395 }
373396 # Bug 14385: we need makeTitleSafe because the new page names may
374397 # be longer than 255 characters.
375 - $newPage = Title::makeTitleSafe( $newNs, $newPageName );
376 - if( !$newPage ) {
377 - $oldLink = $skin->makeKnownLinkObj( $oldPage );
 398+ $newSubpage = Title::makeTitleSafe( $newNs, $newPageName );
 399+ if( !$newSubpage ) {
 400+ $oldLink = $skin->makeKnownLinkObj( $oldSubpage );
378401 $extraOutput []= wfMsgHtml( 'movepage-page-unmoved', $oldLink,
379402 htmlspecialchars(Title::makeName( $newNs, $newPageName )));
380403 continue;
381404 }
382405
383406 # This was copy-pasted from Renameuser, bleh.
384 - if ( $newPage->exists() && !$oldPage->isValidMoveTarget( $newPage ) ) {
385 - $link = $skin->makeKnownLinkObj( $newPage );
 407+ if ( $newSubpage->exists() && !$oldSubpage->isValidMoveTarget( $newSubpage ) ) {
 408+ $link = $skin->makeKnownLinkObj( $newSubpage );
386409 $extraOutput []= wfMsgHtml( 'movepage-page-exists', $link );
387410 } else {
388 - $success = $oldPage->moveTo( $newPage, true, $this->reason );
 411+ $success = $oldSubpage->moveTo( $newSubpage, true, $this->reason );
389412 if( $success === true ) {
390 - $oldLink = $skin->makeKnownLinkObj( $oldPage, '', 'redirect=no' );
391 - $newLink = $skin->makeKnownLinkObj( $newPage );
 413+ if ( $this->fixRedirects ) {
 414+ DoubleRedirectJob::fixRedirects( 'move', $oldSubpage, $newSubpage );
 415+ }
 416+ $oldLink = $skin->makeKnownLinkObj( $oldSubpage, '', 'redirect=no' );
 417+ $newLink = $skin->makeKnownLinkObj( $newSubpage );
392418 $extraOutput []= wfMsgHtml( 'movepage-page-moved', $oldLink, $newLink );
393419 } else {
394 - $oldLink = $skin->makeKnownLinkObj( $oldPage );
395 - $newLink = $skin->makeLinkObj( $newPage );
 420+ $oldLink = $skin->makeKnownLinkObj( $oldSubpage );
 421+ $newLink = $skin->makeLinkObj( $newSubpage );
396422 $extraOutput []= wfMsgHtml( 'movepage-page-unmoved', $oldLink, $newLink );
397423 }
398424 }
Index: trunk/phase3/RELEASE-NOTES
@@ -194,6 +194,7 @@
195195 * Special:Recentchangeslinked now includes changes to transcluded pages and
196196 displayed images; also, the "Show changes to pages linked" checkbox now works on
197197 category pages too, showing all links that are not categorizations
 198+* (bug 4578) Automatically fix redirects broken by a page move
198199
199200 === Bug fixes in 1.13 ===
200201
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -1871,6 +1871,9 @@
18721872 'doubleredirectstext' => 'This page lists pages which redirect to other redirect pages.
18731873 Each row contains links to the first and second redirect, as well as the target of the second redirect, which is usually "real" target page, which the first redirect should point to.',
18741874
 1875+'double-redirect-fixed-move' => '[[$1]] has been moved, it is now just a redirect to [[$2]]',
 1876+'double-redirect-fixer' => 'Redirect fixer',
 1877+
18751878 'brokenredirects' => 'Broken redirects',
18761879 'brokenredirects-summary' => '', # do not translate or duplicate this message to other languages
18771880 'brokenredirectstext' => 'The following redirects link to non-existent pages:',
@@ -2500,6 +2503,7 @@
25012504 'imagenocrossnamespace' => 'Cannot move file to non-file namespace',
25022505 'imagetypemismatch' => 'The new file extension does not match its type',
25032506 'imageinvalidfilename' => 'The target file name is invalid',
 2507+'fix-double-redirects' => 'Update any redirects that point to the original title',
25042508
25052509 # Export
25062510 'export' => 'Export pages',

Follow-up revisions

RevisionCommit summaryAuthorDate
r37940Fix for r37928....siebrand08:39, 23 July 2008
r37942Missing file for r37928tstarling08:48, 23 July 2008

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r12647Update copyright year to extend to 2006 in a couple of visible places, per bu...robchurch13:56, 13 January 2006

Status & tagging log