42 public const MAX_DR_JOBS_COUNTER = 10000;
62 parent::__construct(
'fixDoubleRedirect', $page, $params );
63 $this->redirTitle = Title::newFromText( $params[
'redirTitle'] );
74 # Need to use the primary DB to get the redirect table updated in the same transaction
77 [
'redirect',
'page' ],
78 [
'page_namespace',
'page_title' ],
82 'rd_title' => $redirTitle->
getDBkey()
84 if ( !
$res->numRows() ) {
88 $jobQueueGroup = MediaWikiServices::getInstance()->getJobQueueGroup();
89 foreach (
$res as $row ) {
90 $title = Title::makeTitle( $row->page_namespace, $row->page_title );
95 $jobs[] =
new self(
$title, [
97 'redirTitle' => MediaWikiServices::getInstance()
99 ->getPrefixedDBkey( $redirTitle ),
101 # Avoid excessive memory usage
102 if ( count( $jobs ) > self::MAX_DR_JOBS_COUNTER ) {
103 $jobQueueGroup->push( $jobs );
107 $jobQueueGroup->push( $jobs );
114 if ( !$this->redirTitle ) {
120 $services = MediaWikiServices::getInstance();
121 $targetRev = $services->getRevisionLookup()
122 ->getRevisionByTitle( $this->title, 0, RevisionLookup::READ_LATEST );
124 wfDebug( __METHOD__ .
": target redirect already deleted, ignoring" );
128 $content = $targetRev->getContent( SlotRecord::MAIN );
130 if ( !$currentDest || !$currentDest->equals( $this->redirTitle ) ) {
131 wfDebug( __METHOD__ .
": Redirect has changed since the job was queued" );
137 $mw = $services->getMagicWordFactory()->get(
'staticredirect' );
138 if (
$content->matchMagicWord( $mw ) ) {
139 wfDebug( __METHOD__ .
": skipping: suppressed with __STATICREDIRECT__" );
145 $newTitle = self::getFinalDestination( $this->redirTitle );
148 ": skipping: single redirect, circular redirect or invalid redirect destination" );
152 if ( $newTitle->equals( $this->redirTitle ) ) {
155 wfDebug( __METHOD__ .
" : skipping, already good" );
159 $newTitle = Title::makeTitle( $newTitle->getNamespace(), $newTitle->getDBkey(),
160 $currentDest->getFragment(), $newTitle->getInterwiki() );
163 $newContent =
$content->updateRedirect( $newTitle );
165 if ( $newContent->equals(
$content ) ) {
183 $article = $services->getWikiPageFactory()->newFromTitle( $this->title );
186 $reason =
wfMessage(
'double-redirect-fixed-' . $this->params[
'reason'],
187 $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText()
188 )->inContentLanguage()->text();
191 $article->doUserEditContent( $newContent, $user, $reason, $flags );
213 $titleText = CacheKeyHelper::getKeyForPage(
$title );
214 if ( isset( $seenTitles[$titleText] ) ) {
215 wfDebug( __METHOD__,
"Circular redirect detected, aborting" );
219 $seenTitles[$titleText] =
true;
221 if (
$title->isExternal() ) {
229 $row = $dbw->selectRow(
230 [
'redirect',
'page' ],
231 [
'rd_namespace',
'rd_title',
'rd_interwiki' ],
234 'page_namespace' =>
$title->getNamespace(),
235 'page_title' =>
$title->getDBkey()
238 # No redirect from here, chain terminates
241 $dest =
$title = Title::makeTitle(
245 $row->rd_interwiki ??
''
261 if ( !self::$user ) {
262 $username =
wfMessage(
'double-redirect-fixer' )->inContentLanguage()->text();
264 # User::newFromName() can return false on a badly configured wiki.
265 if ( self::$user && !self::$user->isRegistered() ) {
266 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.
Job to fix 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.
Represents a title within MediaWiki.
getNamespace()
Get the namespace index, i.e.
getDBkey()
Get the main part with underscores.
static newFromName( $name, $validate='valid')