40 public const MAX_DR_JOBS_COUNTER = 10000;
60 parent::__construct(
'fixDoubleRedirect', $page,
$params );
61 $this->redirTitle = Title::newFromText(
$params[
'redirTitle'] );
72 # Need to use the primary DB to get the redirect table updated in the same transaction
75 [
'redirect',
'page' ],
76 [
'page_namespace',
'page_title' ],
80 'rd_title' => $redirTitle->
getDBkey()
82 if ( !
$res->numRows() ) {
86 $jobQueueGroup = MediaWikiServices::getInstance()->getJobQueueGroup();
87 foreach (
$res as $row ) {
88 $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
93 $jobs[] =
new self(
$title, [
95 'redirTitle' => MediaWikiServices::getInstance()
97 ->getPrefixedDBkey( $redirTitle ),
99 # Avoid excessive memory usage
100 if ( count( $jobs ) > self::MAX_DR_JOBS_COUNTER ) {
101 $jobQueueGroup->push( $jobs );
105 $jobQueueGroup->push( $jobs );
112 if ( !$this->redirTitle ) {
118 if ( !$this->title->canExist() ) {
125 $services = MediaWikiServices::getInstance();
126 $targetRev = $services->getRevisionLookup()
127 ->getRevisionByTitle( $this->title, 0, RevisionLookup::READ_LATEST );
129 wfDebug( __METHOD__ .
": target redirect already deleted, ignoring" );
133 $content = $targetRev->getContent( SlotRecord::MAIN );
135 if ( !$currentDest || !$currentDest->equals( $this->redirTitle ) ) {
136 wfDebug( __METHOD__ .
": Redirect has changed since the job was queued" );
142 $mw = $services->getMagicWordFactory()->get(
'staticredirect' );
143 if (
$content->matchMagicWord( $mw ) ) {
144 wfDebug( __METHOD__ .
": skipping: suppressed with __STATICREDIRECT__" );
153 ": skipping: single redirect, circular redirect or invalid redirect destination" );
157 if ( $newTitle->equals( $this->redirTitle ) ) {
160 wfDebug( __METHOD__ .
" : skipping, already good" );
164 $newTitle = Title::makeTitle( $newTitle->getNamespace(), $newTitle->getDBkey(),
165 $currentDest->getFragment(), $newTitle->getInterwiki() );
168 $newContent =
$content->updateRedirect( $newTitle );
170 if ( $newContent->equals(
$content ) ) {
176 $user = $this->getUser();
188 $article = $services->getWikiPageFactory()->newFromTitle( $this->title );
191 $reason =
wfMessage(
'double-redirect-fixed-' . $this->params[
'reason'],
192 $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText()
193 )->inContentLanguage()->text();
196 $article->doUserEditContent( $newContent, $user, $reason, $flags );
218 $titleText = CacheKeyHelper::getKeyForPage(
$title );
219 if ( isset( $seenTitles[$titleText] ) ) {
220 wfDebug( __METHOD__,
"Circular redirect detected, aborting" );
224 $seenTitles[$titleText] =
true;
234 $row = $dbw->selectRow(
235 [
'redirect',
'page' ],
236 [
'rd_namespace',
'rd_title',
'rd_interwiki' ],
243 # No redirect from here, chain terminates
246 $dest =
$title = Title::makeTitle(
250 $row->rd_interwiki ??
''
265 private function getUser() {
266 if ( !self::$user ) {
267 $username =
wfMessage(
'double-redirect-fixer' )->inContentLanguage()->text();
269 # User::newFromName() can return false on a badly configured wiki.
270 if ( self::$user && !self::$user->isRegistered() ) {
271 self::$user->addToDatabase();
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Fix any double redirects after moving a page.
static getFinalDestination( $title)
Get the final destination of a redirect.
__construct(PageReference $page, array $params)
static fixRedirects( $reason, $redirTitle)
Insert jobs into the job queue to fix redirects to the given title.
Class to both describe a background job and handle jobs.
array $params
Array of job parameters.
static newFromName( $name, $validate='valid')