47 public const MAX_DR_JOBS_COUNTER = 10000;
58 private $revisionLookup;
61 private $magicWordFactory;
64 private $wikiPageFactory;
85 parent::__construct(
'fixDoubleRedirect', $page,
$params );
86 $this->redirTitle = Title::newFromText(
$params[
'redirTitle'] );
87 $this->revisionLookup = $revisionLookup;
88 $this->magicWordFactory = $magicWordFactory;
89 $this->wikiPageFactory = $wikiPageFactory;
100 # Need to use the primary DB to get the redirect table updated in the same transaction
102 $dbw = $services->getConnectionProvider()->getPrimaryDatabase();
103 $res = $dbw->newSelectQueryBuilder()
104 ->select( [
'page_namespace',
'page_title' ] )
106 ->join(
'page',
null,
'page_id = rd_from' )
107 ->where( [
'rd_namespace' => $redirTitle->
getNamespace(),
'rd_title' => $redirTitle->
getDBkey() ] )
108 ->andWhere( [
'rd_interwiki' =>
'' ] )
109 ->caller( __METHOD__ )->fetchResultSet();
110 if ( !$res->numRows() ) {
114 $jobQueueGroup = $services->getJobQueueGroup();
115 foreach ( $res as $row ) {
116 $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
125 'redirTitle' => $services->getTitleFormatter()
126 ->getPrefixedDBkey( $redirTitle )
128 $services->getRevisionLookup(),
129 $services->getMagicWordFactory(),
130 $services->getWikiPageFactory()
132 # Avoid excessive memory usage
133 if ( count( $jobs ) > self::MAX_DR_JOBS_COUNTER ) {
134 $jobQueueGroup->push( $jobs );
138 $jobQueueGroup->push( $jobs );
145 if ( !$this->redirTitle ) {
151 if ( !$this->title->canExist() ) {
158 $targetRev = $this->revisionLookup
159 ->getRevisionByTitle( $this->title, 0, IDBAccessObject::READ_LATEST );
161 wfDebug( __METHOD__ .
": target redirect already deleted, ignoring" );
165 $content = $targetRev->getContent( SlotRecord::MAIN );
166 $currentDest = $content ? $content->getRedirectTarget() :
null;
167 if ( !$currentDest || !$currentDest->equals( $this->redirTitle ) ) {
168 wfDebug( __METHOD__ .
": Redirect has changed since the job was queued" );
174 $mw = $this->magicWordFactory->get(
'staticredirect' );
175 if ( $content->matchMagicWord( $mw ) ) {
176 wfDebug( __METHOD__ .
": skipping: suppressed with __STATICREDIRECT__" );
185 ": skipping: single redirect, circular redirect or invalid redirect destination" );
189 if ( $newTitle->equals( $this->redirTitle ) ) {
192 wfDebug( __METHOD__ .
" : skipping, already good" );
196 $newTitle = Title::makeTitle( $newTitle->getNamespace(), $newTitle->getDBkey(),
197 $currentDest->getFragment(), $newTitle->getInterwiki() );
200 $newContent = $content->updateRedirect( $newTitle );
202 if ( $newContent->equals( $content ) ) {
208 $user = $this->getUser();
220 $article = $this->wikiPageFactory->newFromTitle( $this->title );
223 $reason =
wfMessage(
'double-redirect-fixed-' . $this->params[
'reason'],
224 $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText()
225 )->inContentLanguage()->text();
228 $article->doUserEditContent( $newContent, $user, $reason, $flags );
250 $titleText = CacheKeyHelper::getKeyForPage(
$title );
251 if ( isset( $seenTitles[$titleText] ) ) {
252 wfDebug( __METHOD__,
"Circular redirect detected, aborting" );
256 $seenTitles[$titleText] =
true;
265 $row = $dbw->newSelectQueryBuilder()
266 ->select( [
'rd_namespace',
'rd_title',
'rd_interwiki' ] )
268 ->join(
'page',
null,
'page_id = rd_from' )
271 ->caller( __METHOD__ )->fetchRow();
273 # No redirect from here, chain terminates
276 $dest =
$title = Title::makeTitle(
295 private function getUser() {
296 if ( !self::$user ) {
297 $username =
wfMessage(
'double-redirect-fixer' )->inContentLanguage()->text();
298 self::$user = User::newFromName( $username );
299 # User::newFromName() can return false on a badly configured wiki.
300 if ( self::$user && !self::$user->isRegistered() ) {
301 self::$user->addToDatabase();
310class_alias( DoubleRedirectJob::class,
'DoubleRedirectJob' );
const EDIT_INTERNAL
Signal that the page retrieve/save cycle happened entirely in this request.
const EDIT_UPDATE
Article is assumed to be pre-existing, fail if it doesn't exist.
const EDIT_MINOR
Mark this edit minor, if the user is allowed to do so.
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.
Service for creating WikiPage objects.