r37942 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r37941‎ | r37942 | r37943 >
Date:08:48, 23 July 2008
Author:tstarling
Status:old
Tags:
Comment:
Missing file for r37928
Modified paths:
  • /trunk/phase3/includes/DoubleRedirectJob.php (added) (history)

Diff [purge]

Index: trunk/phase3/includes/DoubleRedirectJob.php
@@ -0,0 +1,155 @@
 2+<?php
 3+
 4+class DoubleRedirectJob extends Job {
 5+ var $reason, $redirTitle, $destTitleText;
 6+ static $user;
 7+
 8+ /**
 9+ * Insert jobs into the job queue to fix redirects to the given title
 10+ * @param string $type The reason for the fix, see message double-redirect-fixed-<reason>
 11+ * @param Title $redirTitle The title which has changed, redirects pointing to this title are fixed
 12+ */
 13+ public static function fixRedirects( $reason, $redirTitle, $destTitle = false ) {
 14+ # Need to use the master to get the redirect table updated in the same transaction
 15+ $dbw = wfGetDB( DB_MASTER );
 16+ $res = $dbw->select(
 17+ array( 'redirect', 'page' ),
 18+ array( 'page_namespace', 'page_title' ),
 19+ array(
 20+ 'page_id = rd_from',
 21+ 'rd_namespace' => $redirTitle->getNamespace(),
 22+ 'rd_title' => $redirTitle->getDBkey()
 23+ ), __METHOD__ );
 24+ if ( !$res->numRows() ) {
 25+ return;
 26+ }
 27+ $jobs = array();
 28+ foreach ( $res as $row ) {
 29+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
 30+ if ( !$title ) {
 31+ continue;
 32+ }
 33+
 34+ $jobs[] = new self( $title, array(
 35+ 'reason' => $reason,
 36+ 'redirTitle' => $redirTitle->getPrefixedDBkey() ) );
 37+ # Avoid excessive memory usage
 38+ if ( count( $jobs ) > 10000 ) {
 39+ Job::batchInsert( $jobs );
 40+ $jobs = array();
 41+ }
 42+ }
 43+ Job::batchInsert( $jobs );
 44+ }
 45+ function __construct( $title, $params = false, $id = 0 ) {
 46+ parent::__construct( 'fixDoubleRedirect', $title, $params, $id );
 47+ $this->reason = $params['reason'];
 48+ $this->redirTitle = Title::newFromText( $params['redirTitle'] );
 49+ $this->destTitleText = !empty( $params['destTitle'] ) ? $params['destTitle'] : '';
 50+ }
 51+
 52+ function run() {
 53+ if ( !$this->redirTitle ) {
 54+ $this->setLastError( 'Invalid title' );
 55+ return false;
 56+ }
 57+
 58+ $targetRev = Revision::newFromTitle( $this->title );
 59+ if ( !$targetRev ) {
 60+ wfDebug( __METHOD__.": target redirect already deleted, ignoring\n" );
 61+ return true;
 62+ }
 63+ $text = $targetRev->getText();
 64+ $currentDest = Title::newFromRedirect( $text );
 65+ if ( !$currentDest || !$currentDest->equals( $this->redirTitle ) ) {
 66+ wfDebug( __METHOD__.": Redirect has changed since the job was queued\n" );
 67+ return true;
 68+ }
 69+
 70+ # Find the current final destination
 71+ $newTitle = self::getFinalDestination( $this->redirTitle );
 72+ if ( !$newTitle ) {
 73+ wfDebug( __METHOD__.": skipping: single redirect, circular redirect or invalid redirect destination\n" );
 74+ return true;
 75+ }
 76+ if ( $newTitle->equals( $this->redirTitle ) ) {
 77+ # The redirect is already right, no need to change it
 78+ # This can happen if the page was moved back (say after vandalism)
 79+ wfDebug( __METHOD__.": skipping, already good\n" );
 80+ }
 81+
 82+ # Fix the text
 83+ # Remember that redirect pages can have categories, templates, etc.,
 84+ # so the regex has to be fairly general
 85+ $newText = preg_replace( '/ \[ \[ [^\]]* \] \] /x',
 86+ '[[' . $newTitle->getPrefixedText() . ']]',
 87+ $text, 1 );
 88+
 89+ if ( $newText === $text ) {
 90+ $this->setLastError( 'Text unchanged???' );
 91+ return false;
 92+ }
 93+
 94+ # Save it
 95+ global $wgUser;
 96+ $oldUser = $wgUser;
 97+ $wgUser = $this->getUser();
 98+ $article = new Article( $this->title );
 99+ $reason = wfMsgForContent( 'double-redirect-fixed-' . $this->reason,
 100+ $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText() );
 101+ $article->doEdit( $newText, $reason, EDIT_UPDATE | EDIT_SUPPRESS_RC );
 102+ $wgUser = $oldUser;
 103+
 104+ return true;
 105+ }
 106+
 107+ /**
 108+ * Get the final destination of a redirect
 109+ * Returns false if the specified title is not a redirect, or if it is a circular redirect
 110+ */
 111+ public static function getFinalDestination( $title ) {
 112+ $dbw = wfGetDB( DB_MASTER );
 113+
 114+ $seenTitles = array(); # Circular redirect check
 115+ $dest = false;
 116+
 117+ while ( true ) {
 118+ $titleText = $title->getPrefixedDBkey();
 119+ if ( isset( $seenTitles[$titleText] ) ) {
 120+ wfDebug( __METHOD__, "Circular redirect detected, aborting\n" );
 121+ return false;
 122+ }
 123+ $seenTitles[$titleText] = true;
 124+
 125+ $row = $dbw->selectRow(
 126+ array( 'redirect', 'page' ),
 127+ array( 'rd_namespace', 'rd_title' ),
 128+ array(
 129+ 'rd_from=page_id',
 130+ 'page_namespace' => $title->getNamespace(),
 131+ 'page_title' => $title->getDBkey()
 132+ ), __METHOD__ );
 133+ if ( !$row ) {
 134+ # No redirect from here, chain terminates
 135+ break;
 136+ } else {
 137+ $dest = $title = Title::makeTitle( $row->rd_namespace, $row->rd_title );
 138+ }
 139+ }
 140+ return $dest;
 141+ }
 142+
 143+ /**
 144+ * Get a user object for doing edits, from a request-lifetime cache
 145+ */
 146+ function getUser() {
 147+ if ( !self::$user ) {
 148+ self::$user = User::newFromName( wfMsgForContent( 'double-redirect-fixer' ), false );
 149+ if ( !self::$user->isLoggedIn() ) {
 150+ self::$user->addToDatabase();
 151+ }
 152+ }
 153+ return self::$user;
 154+ }
 155+}
 156+
Property changes on: trunk/phase3/includes/DoubleRedirectJob.php
___________________________________________________________________
Name: svn:eol-style
1157 + native

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r37928* (bug 4578) Automatically fix redirects broken by a page move. Works via the...tstarling22:44, 22 July 2008

Status & tagging log