X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiPageSet.php;h=a235532cf31ddab4565725208658f6e99d3932e6;hb=4d609f015dd64528e772bbaa088d378aa26334eb;hp=85c6860e9e52bce99e1be05feec3acb02266e859;hpb=8e8b4167ce356e3d516f4607c1c72a909bb3c24c;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiPageSet.php b/includes/api/ApiPageSet.php index 85c6860e9e..a235532cf3 100644 --- a/includes/api/ApiPageSet.php +++ b/includes/api/ApiPageSet.php @@ -71,6 +71,7 @@ class ApiPageSet extends ApiBase { private $mInterwikiTitles = []; /** @var Title[] */ private $mPendingRedirectIDs = []; + private $mPendingRedirectSpecialPages = []; // [dbkey] => [ Title $from, Title $to ] private $mResolvedRedirectTitles = []; private $mConvertedTitles = []; private $mGoodRevIDs = []; @@ -813,6 +814,8 @@ class ApiPageSet extends ApiBase { // Get validated and normalized title objects $linkBatch = $this->processTitlesArray( $titles ); if ( $linkBatch->isEmpty() ) { + // There might be special-page redirects + $this->resolvePendingRedirects(); return; } @@ -1033,7 +1036,7 @@ class ApiPageSet extends ApiBase { // Repeat until all redirects have been resolved // The infinite loop is prevented by keeping all known pages in $this->mAllPages - while ( $this->mPendingRedirectIDs ) { + while ( $this->mPendingRedirectIDs || $this->mPendingRedirectSpecialPages ) { // Resolve redirects by querying the pagelinks table, and repeat the process // Create a new linkBatch object for the next pass $linkBatch = $this->getRedirectTargets(); @@ -1067,56 +1070,76 @@ class ApiPageSet extends ApiBase { $titlesToResolve = []; $db = $this->getDB(); - $res = $db->select( - 'redirect', - [ - 'rd_from', - 'rd_namespace', - 'rd_fragment', - 'rd_interwiki', - 'rd_title' - ], [ 'rd_from' => array_keys( $this->mPendingRedirectIDs ) ], - __METHOD__ - ); - foreach ( $res as $row ) { - $rdfrom = intval( $row->rd_from ); - $from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText(); - $to = Title::makeTitle( - $row->rd_namespace, - $row->rd_title, - $row->rd_fragment, - $row->rd_interwiki - ); - $this->mResolvedRedirectTitles[$from] = $this->mPendingRedirectIDs[$rdfrom]; - unset( $this->mPendingRedirectIDs[$rdfrom] ); - if ( $to->isExternal() ) { - $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki(); - } elseif ( !isset( $this->mAllPages[$to->getNamespace()][$to->getDBkey()] ) ) { - $titlesToResolve[] = $to; + if ( $this->mPendingRedirectIDs ) { + $res = $db->select( + 'redirect', + [ + 'rd_from', + 'rd_namespace', + 'rd_fragment', + 'rd_interwiki', + 'rd_title' + ], [ 'rd_from' => array_keys( $this->mPendingRedirectIDs ) ], + __METHOD__ + ); + foreach ( $res as $row ) { + $rdfrom = intval( $row->rd_from ); + $from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText(); + $to = Title::makeTitle( + $row->rd_namespace, + $row->rd_title, + $row->rd_fragment, + $row->rd_interwiki + ); + $this->mResolvedRedirectTitles[$from] = $this->mPendingRedirectIDs[$rdfrom]; + unset( $this->mPendingRedirectIDs[$rdfrom] ); + if ( $to->isExternal() ) { + $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki(); + } elseif ( !isset( $this->mAllPages[$to->getNamespace()][$to->getDBkey()] ) ) { + $titlesToResolve[] = $to; + } + $this->mRedirectTitles[$from] = $to; } - $this->mRedirectTitles[$from] = $to; - } - if ( $this->mPendingRedirectIDs ) { - // We found pages that aren't in the redirect table - // Add them - foreach ( $this->mPendingRedirectIDs as $id => $title ) { - $page = WikiPage::factory( $title ); - $rt = $page->insertRedirect(); - if ( !$rt ) { - // What the hell. Let's just ignore this - continue; + if ( $this->mPendingRedirectIDs ) { + // We found pages that aren't in the redirect table + // Add them + foreach ( $this->mPendingRedirectIDs as $id => $title ) { + $page = WikiPage::factory( $title ); + $rt = $page->insertRedirect(); + if ( !$rt ) { + // What the hell. Let's just ignore this + continue; + } + if ( $rt->isExternal() ) { + $this->mInterwikiTitles[$rt->getPrefixedText()] = $rt->getInterwiki(); + } elseif ( !isset( $this->mAllPages[$rt->getNamespace()][$rt->getDBkey()] ) ) { + $titlesToResolve[] = $rt; + } + $from = $title->getPrefixedText(); + $this->mResolvedRedirectTitles[$from] = $title; + $this->mRedirectTitles[$from] = $rt; + unset( $this->mPendingRedirectIDs[$id] ); } - if ( $rt->isExternal() ) { - $this->mInterwikiTitles[$rt->getPrefixedText()] = $rt->getInterwiki(); - } elseif ( !isset( $this->mAllPages[$rt->getNamespace()][$rt->getDBkey()] ) ) { - $titlesToResolve[] = $rt; + } + } + + if ( $this->mPendingRedirectSpecialPages ) { + foreach ( $this->mPendingRedirectSpecialPages as $key => list( $from, $to ) ) { + $fromKey = $from->getPrefixedText(); + $this->mResolvedRedirectTitles[$fromKey] = $from; + $this->mRedirectTitles[$fromKey] = $to; + if ( $to->isExternal() ) { + $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki(); + } elseif ( !isset( $this->mAllPages[$to->getNamespace()][$to->getDBkey()] ) ) { + $titlesToResolve[] = $to; } - $from = $title->getPrefixedText(); - $this->mResolvedRedirectTitles[$from] = $title; - $this->mRedirectTitles[$from] = $rt; - unset( $this->mPendingRedirectIDs[$id] ); } + $this->mPendingRedirectSpecialPages = []; + + // Set private caching since we don't know what criteria the + // special pages used to decide on these redirects. + $this->mCacheMode = 'private'; } return $this->processTitlesArray( $titlesToResolve ); @@ -1197,8 +1220,26 @@ class ApiPageSet extends ApiBase { $dbkey = $titleObj->getDBkey(); if ( !isset( $this->mAllSpecials[$ns][$dbkey] ) ) { $this->mAllSpecials[$ns][$dbkey] = $this->mFakePageId; - $this->mSpecialTitles[$this->mFakePageId] = $titleObj; - $this->mFakePageId--; + $target = null; + if ( $ns === NS_SPECIAL && $this->mResolveRedirects ) { + $special = SpecialPageFactory::getPage( $dbkey ); + if ( $special instanceof RedirectSpecialArticle ) { + // Only RedirectSpecialArticle is intended to redirect to an article, other kinds of + // RedirectSpecialPage are probably applying weird URL parameters we don't want to handle. + $context = new DerivativeContext( $this ); + $context->setTitle( $titleObj ); + $context->setRequest( new FauxRequest ); + $special->setContext( $context ); + list( /* $alias */, $subpage ) = SpecialPageFactory::resolveAlias( $dbkey ); + $target = $special->getRedirect( $subpage ); + } + } + if ( $target ) { + $this->mPendingRedirectSpecialPages[$dbkey] = [ $titleObj, $target ]; + } else { + $this->mSpecialTitles[$this->mFakePageId] = $titleObj; + $this->mFakePageId--; + } } } else { // Regular page