44 public const MAX_DR_JOBS_COUNTER = 10000;
55 private $revisionLookup;
58 private $magicWordFactory;
61 private $wikiPageFactory;
82 parent::__construct(
'fixDoubleRedirect', $page,
$params );
83 $this->redirTitle = Title::newFromText(
$params[
'redirTitle'] );
84 $this->revisionLookup = $revisionLookup;
85 $this->magicWordFactory = $magicWordFactory;
86 $this->wikiPageFactory = $wikiPageFactory;
97 # Need to use the primary DB to get the redirect table updated in the same transaction
98 $services = MediaWikiServices::getInstance();
99 $dbw = $services->getConnectionProvider()->getPrimaryDatabase();
100 $res = $dbw->newSelectQueryBuilder()
101 ->select( [
'page_namespace',
'page_title' ] )
103 ->join(
'page',
null,
'page_id = rd_from' )
104 ->where( [
'rd_namespace' => $redirTitle->
getNamespace(),
'rd_title' => $redirTitle->
getDBkey() ] )
105 ->andWhere( [
'rd_interwiki' =>
'' ] )
106 ->caller( __METHOD__ )->fetchResultSet();
107 if ( !$res->numRows() ) {
111 $jobQueueGroup = $services->getJobQueueGroup();
112 foreach ( $res as $row ) {
113 $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
122 'redirTitle' => $services->getTitleFormatter()
123 ->getPrefixedDBkey( $redirTitle )
125 $services->getRevisionLookup(),
126 $services->getMagicWordFactory(),
127 $services->getWikiPageFactory()
129 # Avoid excessive memory usage
130 if ( count( $jobs ) > self::MAX_DR_JOBS_COUNTER ) {
131 $jobQueueGroup->push( $jobs );
135 $jobQueueGroup->push( $jobs );
142 if ( !$this->redirTitle ) {
148 if ( !$this->title->canExist() ) {
155 $targetRev = $this->revisionLookup
156 ->getRevisionByTitle( $this->title, 0, IDBAccessObject::READ_LATEST );
158 wfDebug( __METHOD__ .
": target redirect already deleted, ignoring" );
162 $content = $targetRev->getContent( SlotRecord::MAIN );
163 $currentDest = $content ? $content->getRedirectTarget() :
null;
164 if ( !$currentDest || !$currentDest->equals( $this->redirTitle ) ) {
165 wfDebug( __METHOD__ .
": Redirect has changed since the job was queued" );
171 $mw = $this->magicWordFactory->get(
'staticredirect' );
172 if ( $content->matchMagicWord( $mw ) ) {
173 wfDebug( __METHOD__ .
": skipping: suppressed with __STATICREDIRECT__" );
179 $newTitle = self::getFinalDestination( $this->redirTitle );
182 ": skipping: single redirect, circular redirect or invalid redirect destination" );
186 if ( $newTitle->equals( $this->redirTitle ) ) {
189 wfDebug( __METHOD__ .
" : skipping, already good" );
193 $newTitle = Title::makeTitle( $newTitle->getNamespace(), $newTitle->getDBkey(),
194 $currentDest->getFragment(), $newTitle->getInterwiki() );
197 $newContent = $content->updateRedirect( $newTitle );
199 if ( $newContent->equals( $content ) ) {
205 $user = $this->getUser();
217 $article = $this->wikiPageFactory->newFromTitle( $this->title );
220 $reason =
wfMessage(
'double-redirect-fixed-' . $this->params[
'reason'],
221 $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText()
222 )->inContentLanguage()->text();
225 $article->doUserEditContent( $newContent, $user, $reason, $flags );
240 $dbw = MediaWikiServices::getInstance()->getConnectionProvider()->getPrimaryDatabase();
247 $titleText = CacheKeyHelper::getKeyForPage(
$title );
248 if ( isset( $seenTitles[$titleText] ) ) {
249 wfDebug( __METHOD__,
"Circular redirect detected, aborting" );
253 $seenTitles[$titleText] =
true;
262 $row = $dbw->newSelectQueryBuilder()
263 ->select( [
'rd_namespace',
'rd_title',
'rd_interwiki' ] )
265 ->join(
'page',
null,
'page_id = rd_from' )
268 ->caller( __METHOD__ )->fetchRow();
270 # No redirect from here, chain terminates
273 $dest =
$title = Title::makeTitle(
292 private function getUser() {
293 if ( !self::$user ) {
294 $username =
wfMessage(
'double-redirect-fixer' )->inContentLanguage()->text();
295 self::$user = User::newFromName( $username );
296 # User::newFromName() can return false on a badly configured wiki.
297 if ( self::$user && !self::$user->isRegistered() ) {
298 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.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
array $params
The job parameters.
setLastError( $error)
This is actually implemented in the Job class.
Fix any double redirects after moving a page.
static getFinalDestination( $title)
Get the final destination of a redirect.
__construct(PageReference $page, array $params, RevisionLookup $revisionLookup, MagicWordFactory $magicWordFactory, WikiPageFactory $wikiPageFactory)
static fixRedirects( $reason, $redirTitle)
Insert jobs into the job queue to fix redirects to the given title.
Describe and execute a background job.
Service for creating WikiPage objects.