MediaWiki  1.23.13
DoubleRedirectJob.php
Go to the documentation of this file.
1 <?php
29 class DoubleRedirectJob extends Job {
33  private $reason;
34 
38  private $redirTitle;
39 
41  private static $user;
42 
51  public static function fixRedirects( $reason, $redirTitle, $destTitle = false ) {
52  # Need to use the master to get the redirect table updated in the same transaction
53  $dbw = wfGetDB( DB_MASTER );
54  $res = $dbw->select(
55  array( 'redirect', 'page' ),
56  array( 'page_namespace', 'page_title' ),
57  array(
58  'page_id = rd_from',
59  'rd_namespace' => $redirTitle->getNamespace(),
60  'rd_title' => $redirTitle->getDBkey()
61  ), __METHOD__ );
62  if ( !$res->numRows() ) {
63  return;
64  }
65  $jobs = array();
66  foreach ( $res as $row ) {
67  $title = Title::makeTitle( $row->page_namespace, $row->page_title );
68  if ( !$title ) {
69  continue;
70  }
71 
72  $jobs[] = new self( $title, array(
73  'reason' => $reason,
74  'redirTitle' => $redirTitle->getPrefixedDBkey() ) );
75  # Avoid excessive memory usage
76  if ( count( $jobs ) > 10000 ) {
77  JobQueueGroup::singleton()->push( $jobs );
78  $jobs = array();
79  }
80  }
81  JobQueueGroup::singleton()->push( $jobs );
82  }
83 
89  function __construct( $title, $params = false ) {
90  parent::__construct( 'fixDoubleRedirect', $title, $params );
91  $this->reason = $params['reason'];
92  $this->redirTitle = Title::newFromText( $params['redirTitle'] );
93  }
94 
98  function run() {
99  if ( !$this->redirTitle ) {
100  $this->setLastError( 'Invalid title' );
101 
102  return false;
103  }
104 
105  $targetRev = Revision::newFromTitle( $this->title, false, Revision::READ_LATEST );
106  if ( !$targetRev ) {
107  wfDebug( __METHOD__ . ": target redirect already deleted, ignoring\n" );
108 
109  return true;
110  }
111  $content = $targetRev->getContent();
112  $currentDest = $content ? $content->getRedirectTarget() : null;
113  if ( !$currentDest || !$currentDest->equals( $this->redirTitle ) ) {
114  wfDebug( __METHOD__ . ": Redirect has changed since the job was queued\n" );
115 
116  return true;
117  }
118 
119  // Check for a suppression tag (used e.g. in periodically archived discussions)
120  $mw = MagicWord::get( 'staticredirect' );
121  if ( $content->matchMagicWord( $mw ) ) {
122  wfDebug( __METHOD__ . ": skipping: suppressed with __STATICREDIRECT__\n" );
123 
124  return true;
125  }
126 
127  // Find the current final destination
128  $newTitle = self::getFinalDestination( $this->redirTitle );
129  if ( !$newTitle ) {
130  wfDebug( __METHOD__ .
131  ": skipping: single redirect, circular redirect or invalid redirect destination\n" );
132 
133  return true;
134  }
135  if ( $newTitle->equals( $this->redirTitle ) ) {
136  // The redirect is already right, no need to change it
137  // This can happen if the page was moved back (say after vandalism)
138  wfDebug( __METHOD__ . " : skipping, already good\n" );
139  }
140 
141  // Preserve fragment (bug 14904)
142  $newTitle = Title::makeTitle( $newTitle->getNamespace(), $newTitle->getDBkey(),
143  $currentDest->getFragment(), $newTitle->getInterwiki() );
144 
145  // Fix the text
146  $newContent = $content->updateRedirect( $newTitle );
147 
148  if ( $newContent->equals( $content ) ) {
149  $this->setLastError( 'Content unchanged???' );
150 
151  return false;
152  }
153 
154  $user = $this->getUser();
155  if ( !$user ) {
156  $this->setLastError( 'Invalid user' );
157 
158  return false;
159  }
160 
161  // Save it
162  global $wgUser;
163  $oldUser = $wgUser;
164  $wgUser = $user;
165  $article = WikiPage::factory( $this->title );
166 
167  // Messages: double-redirect-fixed-move, double-redirect-fixed-maintenance
168  $reason = wfMessage( 'double-redirect-fixed-' . $this->reason,
169  $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText()
170  )->inContentLanguage()->text();
171  $article->doEditContent( $newContent, $reason, EDIT_UPDATE | EDIT_SUPPRESS_RC, false, $user );
172  $wgUser = $oldUser;
173 
174  return true;
175  }
176 
184  public static function getFinalDestination( $title ) {
185  $dbw = wfGetDB( DB_MASTER );
186 
187  // Circular redirect check
188  $seenTitles = array();
189  $dest = false;
190 
191  while ( true ) {
192  $titleText = $title->getPrefixedDBkey();
193  if ( isset( $seenTitles[$titleText] ) ) {
194  wfDebug( __METHOD__, "Circular redirect detected, aborting\n" );
195 
196  return false;
197  }
198  $seenTitles[$titleText] = true;
199 
200  if ( $title->isExternal() ) {
201  // If the target is interwiki, we have to break early (bug 40352).
202  // Otherwise it will look up a row in the local page table
203  // with the namespace/page of the interwiki target which can cause
204  // unexpected results (e.g. X -> foo:Bar -> Bar -> .. )
205  break;
206  }
207 
208  $row = $dbw->selectRow(
209  array( 'redirect', 'page' ),
210  array( 'rd_namespace', 'rd_title', 'rd_interwiki' ),
211  array(
212  'rd_from=page_id',
213  'page_namespace' => $title->getNamespace(),
214  'page_title' => $title->getDBkey()
215  ), __METHOD__ );
216  if ( !$row ) {
217  # No redirect from here, chain terminates
218  break;
219  } else {
220  $dest = $title = Title::makeTitle(
221  $row->rd_namespace,
222  $row->rd_title,
223  '',
224  $row->rd_interwiki
225  );
226  }
227  }
228 
229  return $dest;
230  }
231 
239  function getUser() {
240  if ( !self::$user ) {
241  $username = wfMessage( 'double-redirect-fixer' )->inContentLanguage()->text();
242  self::$user = User::newFromName( $username );
243  # User::newFromName() can return false on a badly configured wiki.
244  if ( self::$user && !self::$user->isLoggedIn() ) {
245  self::$user->addToDatabase();
246  }
247  }
248 
249  return self::$user;
250  }
251 }
Title\makeTitle
static & makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:398
$wgUser
$wgUser
Definition: Setup.php:572
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:189
DB_MASTER
const DB_MASTER
Definition: Defines.php:56
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
Title\getPrefixedDBkey
getPrefixedDBkey()
Get the prefixed database key form.
Definition: Title.php:1357
wfGetDB
& wfGetDB( $db, $groups=array(), $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:3706
DoubleRedirectJob\__construct
__construct( $title, $params=false)
Definition: DoubleRedirectJob.php:87
DoubleRedirectJob\getFinalDestination
static getFinalDestination( $title)
Get the final destination of a redirect.
Definition: DoubleRedirectJob.php:182
Job\$title
Title $title
Definition: Job.php:38
DoubleRedirectJob\getUser
getUser()
Get a user object for doing edits, from a request-lifetime cache False will be returned if the user n...
Definition: DoubleRedirectJob.php:237
MagicWord\get
static & get( $id)
Factory: creates an object representing an ID.
Definition: MagicWord.php:238
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:389
Title\isExternal
isExternal()
Is this Title interwiki?
Definition: Title.php:767
IDBAccessObject\READ_LATEST
const READ_LATEST
Definition: IDBAccessObject.php:49
Job\setLastError
setLastError( $error)
Definition: Job.php:317
DoubleRedirectJob
Job to fix double redirects after moving a page.
Definition: DoubleRedirectJob.php:29
title
to move a page</td >< td > &*You are moving the page across *A non empty talk page already exists under the new or *You uncheck the box below In those you will have to move or merge the page manually if desired</td >< td > be sure to &You are responsible for making sure that links continue to point where they are supposed to go Note that the page will &a page at the new title
Definition: All_system_messages.txt:2703
Job
Class to both describe a background job and handle jobs.
Definition: Job.php:31
Title\getDBkey
getDBkey()
Get the main part with underscores.
Definition: Title.php:857
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:103
Title\getNamespace
getNamespace()
Get the namespace index, i.e.
Definition: Title.php:880
wfMessage
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing after in associative array form externallinks including delete and has completed for all link tables default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
DoubleRedirectJob\fixRedirects
static fixRedirects( $reason, $redirTitle, $destTitle=false)
Insert jobs into the job queue to fix redirects to the given title.
Definition: DoubleRedirectJob.php:49
Revision\newFromTitle
static newFromTitle( $title, $id=0, $flags=0)
Load either the current, or a specified, revision that's attached to a given title.
Definition: Revision.php:106
wfDebug
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:980
DoubleRedirectJob\$redirTitle
Title $redirTitle
The title which has changed, redirects pointing to this title are fixed.
Definition: DoubleRedirectJob.php:36
Job\$params
array bool $params
Array of job parameters or false if none *.
Definition: Job.php:34
EDIT_UPDATE
const EDIT_UPDATE
Definition: Defines.php:190
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:237
Title
Represents a title within MediaWiki.
Definition: Title.php:35
DoubleRedirectJob\$user
static $user
Definition: DoubleRedirectJob.php:39
JobQueueGroup\singleton
static singleton( $wiki=false)
Definition: JobQueueGroup.php:61
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
EDIT_SUPPRESS_RC
const EDIT_SUPPRESS_RC
Definition: Defines.php:192
DoubleRedirectJob\run
run()
Definition: DoubleRedirectJob.php:96
$article
Using a hook running we can avoid having all this option specific stuff in our mainline code Using the function array $article
Definition: hooks.txt:78
$res
$res
Definition: database.txt:21
DoubleRedirectJob\$reason
string $reason
Reason for the change, 'maintenance' or 'move'.
Definition: DoubleRedirectJob.php:32