33 public const MAX_DR_JOBS_COUNTER = 10000;
44 private $revisionLookup;
47 private $magicWordFactory;
50 private $wikiPageFactory;
71 parent::__construct(
'fixDoubleRedirect', $page,
$params );
72 $this->redirTitle = Title::newFromText(
$params[
'redirTitle'] );
73 $this->revisionLookup = $revisionLookup;
74 $this->magicWordFactory = $magicWordFactory;
75 $this->wikiPageFactory = $wikiPageFactory;
86 # Need to use the primary DB to get the redirect table updated in the same transaction
88 $dbw = $services->getConnectionProvider()->getPrimaryDatabase();
89 $res = $dbw->newSelectQueryBuilder()
90 ->select( [
'page_namespace',
'page_title' ] )
92 ->join(
'page',
null,
'page_id = rd_from' )
93 ->where( [
'rd_namespace' => $redirTitle->
getNamespace(),
'rd_title' => $redirTitle->
getDBkey() ] )
94 ->andWhere( [
'rd_interwiki' =>
'' ] )
95 ->caller( __METHOD__ )->fetchResultSet();
96 if ( !$res->numRows() ) {
100 $jobQueueGroup = $services->getJobQueueGroup();
101 foreach ( $res as $row ) {
102 $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
111 'redirTitle' => $services->getTitleFormatter()
112 ->getPrefixedDBkey( $redirTitle )
114 $services->getRevisionLookup(),
115 $services->getMagicWordFactory(),
116 $services->getWikiPageFactory()
118 # Avoid excessive memory usage
119 if ( count( $jobs ) > self::MAX_DR_JOBS_COUNTER ) {
120 $jobQueueGroup->push( $jobs );
124 $jobQueueGroup->push( $jobs );
131 if ( !$this->redirTitle ) {
137 if ( !$this->title->canExist() ) {
144 $targetRev = $this->revisionLookup
145 ->getRevisionByTitle( $this->title, 0, IDBAccessObject::READ_LATEST );
147 wfDebug( __METHOD__ .
": target redirect already deleted, ignoring" );
151 $content = $targetRev->getContent( SlotRecord::MAIN );
152 $currentDest = $content ? $content->getRedirectTarget() :
null;
153 if ( !$currentDest || !$currentDest->equals( $this->redirTitle ) ) {
154 wfDebug( __METHOD__ .
": Redirect has changed since the job was queued" );
160 $mw = $this->magicWordFactory->get(
'staticredirect' );
161 if ( $content->matchMagicWord( $mw ) ) {
162 wfDebug( __METHOD__ .
": skipping: suppressed with __STATICREDIRECT__" );
171 ": skipping: single redirect, circular redirect or invalid redirect destination" );
175 if ( $newTitle->equals( $this->redirTitle ) ) {
178 wfDebug( __METHOD__ .
" : skipping, already good" );
182 $newTitle =
Title::makeTitle( $newTitle->getNamespace(), $newTitle->getDBkey(),
183 $currentDest->getFragment(), $newTitle->getInterwiki() );
186 $newContent = $content->updateRedirect( $newTitle );
188 if ( $newContent->equals( $content ) ) {
194 $user = $this->getUser();
206 $article = $this->wikiPageFactory->newFromTitle( $this->title );
209 $reason =
wfMessage(
'double-redirect-fixed-' . $this->params[
'reason'],
210 $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText()
211 )->inContentLanguage()->text();
214 $article->doUserEditContent( $newContent, $user, $reason, $flags );
236 $titleText = CacheKeyHelper::getKeyForPage(
$title );
237 if ( isset( $seenTitles[$titleText] ) ) {
238 wfDebug( __METHOD__,
"Circular redirect detected, aborting" );
242 $seenTitles[$titleText] =
true;
251 $row = $dbw->newSelectQueryBuilder()
252 ->select( [
'rd_namespace',
'rd_title',
'rd_interwiki' ] )
254 ->join(
'page',
null,
'page_id = rd_from' )
257 ->caller( __METHOD__ )->fetchRow();
259 # No redirect from here, chain terminates
281 private function getUser() {
282 if ( !self::$user ) {
283 $username =
wfMessage(
'double-redirect-fixer' )->inContentLanguage()->text();
284 self::$user = User::newFromName( $username );
285 # User::newFromName() can return false on a badly configured wiki.
286 if ( self::$user && !self::$user->isRegistered() ) {
287 self::$user->addToDatabase();
296class_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.
Helper class for mapping page value objects to a string key.
Service for creating WikiPage objects.