167 if ( !$this->internals ) {
172 $services = MediaWikiServices::getInstance();
173 $linkCache = $services->getLinkCache();
174 $output = $this->parent->getOutput();
175 $linkRenderer = $this->parent->getLinkRenderer();
180 ksort( $this->internals );
185 $linkBatchFactory = $services->getLinkBatchFactory();
186 $lb = $linkBatchFactory->newLinkBatch();
187 $lb->setCaller( __METHOD__ );
189 foreach ( $this->internals as $ns => $entries ) {
190 foreach ( $entries as [
'title' =>
$title,
'pdbk' => $pdbk ] ) {
193 # Skip invalid entries.
194 # Result will be ugly, but prevents crash.
199 # Check if it's a static known link, e.g. interwiki
200 if (
$title->isAlwaysKnown() ) {
201 $classes[$pdbk] =
'';
203 $classes[$pdbk] =
'new';
205 $id = $linkCache->getGoodLinkID( $pdbk );
207 $classes[$pdbk] = $linkRenderer->getLinkClasses(
$title );
208 $output->addLink(
$title, $id );
209 $pagemap[$id] = $pdbk;
210 } elseif ( $linkCache->isBadLink( $pdbk ) ) {
211 $classes[$pdbk] =
'new';
213 # Not in the link cache, add it to the query
219 if ( !$lb->isEmpty() ) {
220 $res =
$dbr->newSelectQueryBuilder()
221 ->select( LinkCache::getSelectFields() )
223 ->where( [ $lb->constructSet(
'page',
$dbr ) ] )
224 ->caller( __METHOD__ )
227 # Fetch data and form into an associative array
228 # non-existent = broken
230 $title = Title::makeTitle(
$s->page_namespace,
$s->page_title );
231 $pdbk =
$title->getPrefixedDBkey();
232 $linkCache->addGoodLinkObjFromRow(
$title,
$s );
233 $output->addLink(
$title,
$s->page_id );
234 $classes[$pdbk] = $linkRenderer->getLinkClasses(
$title );
236 $pagemap[
$s->page_id] = $pdbk;
240 if ( $pagemap !== [] ) {
242 $this->hookRunner->onGetLinkColours( $pagemap, $classes, $this->parent->getTitle() );
245 # Do a second query for different language variants of links and categories
246 if ( $this->languageConverter->hasVariants() ) {
250 # Construct search and replace arrays
252 foreach ( $this->internals as $ns => $entries ) {
253 foreach ( $entries as $index => $entry ) {
254 $pdbk = $entry[
'pdbk'];
256 $query = $entry[
'query'] ?? [];
257 $searchkey =
"<!--LINK'\" $ns:$index-->";
258 $displayTextHtml = $entry[
'text'];
259 if ( isset( $entry[
'selflink'] ) ) {
263 if ( $displayTextHtml ===
'' ) {
266 $displayText =
new HtmlArmor( $displayTextHtml );
268 if ( !isset( $classes[$pdbk] ) ) {
269 $classes[$pdbk] =
'new';
271 if ( $classes[$pdbk] ==
'new' ) {
272 $linkCache->addBadLinkObj(
$title );
273 $output->addLink(
$title, 0 );
274 $link = $linkRenderer->makeBrokenLink(
275 $title, $displayText, [], $query
278 $link = $linkRenderer->makePreloadedLink(
279 $title, $displayText, $classes[$pdbk], [], $query
283 $replacePairs[$searchkey] = $link;
288 $text = preg_replace_callback(
289 '/(<!--LINK\'" .*?-->)/',
290 static function ( array
$matches ) use ( $replacePairs ) {
332 $linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
333 $linkBatch = $linkBatchFactory->newLinkBatch();
335 $output = $this->parent->getOutput();
336 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
337 $titlesToBeConverted =
'';
343 foreach ( $this->internals as $ns => $entries ) {
347 foreach ( $entries as $index => [
'title' =>
$title,
'pdbk' => $pdbk ] ) {
349 if ( !isset( $classes[$pdbk] ) || $classes[$pdbk] ===
'new' ) {
350 $titlesAttrs[] = [ $index,
$title ];
353 $titlesToBeConverted .=
$title->getText() .
"\0";
359 $titlesAllVariants = $this->languageConverter->
360 autoConvertToAllVariants( rtrim( $titlesToBeConverted,
"\0" ) );
361 foreach ( $titlesAllVariants as &$titlesVariant ) {
362 $titlesVariant = explode(
"\0", $titlesVariant );
366 $parentTitle = $this->parent->getTitle();
367 foreach ( $titlesAttrs as $i => [ $index,
$title ] ) {
369 $ns =
$title->getNamespace();
370 $text =
$title->getText();
372 foreach ( $titlesAllVariants as $variantName => $textVariants ) {
373 $textVariant = $textVariants[$i];
374 if ( $textVariant === $text ) {
378 $variantTitle = Title::makeTitle( $ns, $textVariant );
383 if ( $variantTitle->equals( $parentTitle ) && !
$title->hasFragment() ) {
384 $this->internals[$ns][$index][
'selflink'] =
true;
388 $linkBatch->addObj( $variantTitle );
389 $variantMap[$variantTitle->getPrefixedDBkey()][] =
"$ns:$index";
396 foreach ( $output->getCategoryNames() as $category ) {
397 $categoryTitle = Title::makeTitleSafe(
NS_CATEGORY, $category );
398 $linkBatch->addObj( $categoryTitle );
399 $variants = $this->languageConverter->autoConvertToAllVariants( $category );
400 foreach ( $variants as $variant ) {
401 if ( $variant !== $category ) {
402 $variantTitle = Title::makeTitleSafe(
NS_CATEGORY, $variant );
403 if ( $variantTitle ===
null ) {
406 $linkBatch->addObj( $variantTitle );
407 $categoryMap[$variant] = [ $category, $categoryTitle ];
412 if ( !$linkBatch->isEmpty() ) {
416 $varRes =
$dbr->newSelectQueryBuilder()
417 ->select( LinkCache::getSelectFields() )
419 ->where( [ $linkBatch->constructSet(
'page',
$dbr ) ] )
420 ->caller( __METHOD__ )
424 $linkRenderer = $this->parent->getLinkRenderer();
427 foreach ( $varRes as
$s ) {
428 $variantTitle = Title::makeTitle(
$s->page_namespace,
$s->page_title );
429 $varPdbk = $variantTitle->getPrefixedDBkey();
430 $vardbk = $variantTitle->getDBkey();
433 if ( isset( $variantMap[$varPdbk] ) ) {
434 $holderKeys = $variantMap[$varPdbk];
435 $linkCache->addGoodLinkObjFromRow( $variantTitle,
$s );
436 $output->addLink( $variantTitle,
$s->page_id );
440 foreach ( $holderKeys as $key ) {
441 list( $ns, $index ) = explode(
':', $key, 2 );
442 $entry =& $this->internals[$ns][$index];
443 $pdbk = $entry[
'pdbk'];
445 if ( !isset( $classes[$pdbk] ) || $classes[$pdbk] ===
'new' ) {
447 $entry[
'title'] = $variantTitle;
448 $entry[
'pdbk'] = $varPdbk;
451 $classes[$varPdbk] = $linkRenderer->getLinkClasses( $variantTitle );
452 $pagemap[
$s->page_id] = $pdbk;
457 if ( isset( $categoryMap[$vardbk] ) ) {
458 list( $oldkey, $oldtitle ) = $categoryMap[$vardbk];
459 if ( !isset( $varCategories[$oldkey] ) && !$oldtitle->exists() ) {
460 $varCategories[$oldkey] = $vardbk;
464 $this->hookRunner->onGetLinkColours( $pagemap, $classes, $this->parent->getTitle() );
467 if ( $varCategories !== [] ) {
469 $originalCats = $output->getCategories();
470 foreach ( $originalCats as $cat => $sortkey ) {
472 $newCats[$varCategories[$cat] ?? $cat] = $sortkey;
474 $output->setCategories( $newCats );