128 $this->tempIdOffset = $idOffset = $this->parent->nextLinkID();
131 # Renumber internal links
132 foreach ( $other->internals as $ns => $nsLinks ) {
133 foreach ( $nsLinks as $key => $entry ) {
134 $newKey = $idOffset + $key;
135 $this->internals[$ns][
$newKey] = $entry;
140 [ $this,
'mergeForeignCallback' ], $texts );
142 # Renumber interwiki links
143 foreach ( $other->interwikis as $key => $entry ) {
144 $newKey = $idOffset + $key;
145 $this->interwikis[
$newKey] = $entry;
149 [ $this,
'mergeForeignCallback' ], $texts );
151 # Set the parent link ID to be beyond the highest used ID
152 $this->parent->setLinkID( $maxId + 1 );
153 $this->tempIdOffset =
null;
282 if ( !$this->internals ) {
287 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
288 $output = $this->parent->getOutput();
294 ksort( $this->internals );
296 $linkcolour_ids = [];
300 $lb->setCaller( __METHOD__ );
302 foreach ( $this->internals as $ns => $entries ) {
303 foreach ( $entries as $entry ) {
305 $title = $entry[
'title'];
306 $pdbk = $entry[
'pdbk'];
308 # Skip invalid entries.
309 # Result will be ugly, but prevents crash.
314 # Check if it's a static known link, e.g. interwiki
315 if ( $title->isAlwaysKnown() ) {
320 $id = $linkCache->getGoodLinkID( $pdbk );
323 $output->addLink( $title, $id );
324 $linkcolour_ids[$id] =
$pdbk;
325 }
elseif ( $linkCache->isBadLink( $pdbk ) ) {
328 # Not in the link cache, add it to the query
329 $lb->addObj( $title );
334 if ( !$lb->isEmpty() ) {
336 LinkCache::getSelectFields(),
337 [
'page_namespace',
'page_title' ]
343 $lb->constructSet(
'page',
$dbr ),
347 # Fetch data and form into an associative array
348 # non-existent = broken
350 $title = Title::makeTitle(
$s->page_namespace,
$s->page_title );
351 $pdbk = $title->getPrefixedDBkey();
352 $linkCache->addGoodLinkObjFromRow( $title,
$s );
356 $linkcolour_ids[
$s->page_id] =
$pdbk;
360 if ( count( $linkcolour_ids ) ) {
362 Hooks::run(
'GetLinkColours', [ $linkcolour_ids, &
$colours, $this->parent->getTitle() ] );
365 # Do a second query for different language variants of links and categories
366 if ( $this->parent->getContentLanguage()->hasVariants() ) {
370 # Construct search and replace arrays
372 foreach ( $this->internals as $ns => $entries ) {
373 foreach ( $entries as $index => $entry ) {
374 $pdbk = $entry[
'pdbk'];
375 $title = $entry[
'title'];
376 $query = $entry[
'query'] ?? [];
378 $searchkey =
"<!--LINK'\" $key-->";
379 $displayText = $entry[
'text'];
380 if (
isset( $entry[
'selflink'] ) ) {
384 if ( $displayText ===
'' ) {
387 $displayText =
new HtmlArmor( $displayText );
394 $linkCache->addBadLinkObj( $title );
411 '/(<!--LINK\'" .*?-->)/',
457 $output = $this->parent->getOutput();
458 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
459 $titlesToBeConverted =
'';
465 foreach ( $this->internals as $ns => $entries ) {
469 foreach ( $entries as $index => $entry ) {
470 $pdbk = $entry[
'pdbk'];
473 $titlesAttrs[] = [ $index, $entry[
'title'] ];
476 $titlesToBeConverted .= $entry[
'title']->getText() .
"\0";
482 $titlesAllVariants = $this->parent->getContentLanguage()->
483 autoConvertToAllVariants(
rtrim( $titlesToBeConverted,
"\0" ) );
484 $allVariantsName =
array_keys( $titlesAllVariants );
485 foreach ( $titlesAllVariants as &$titlesVariant ) {
486 $titlesVariant = explode(
"\0", $titlesVariant );
490 $parentTitle = $this->parent->getTitle();
491 foreach ( $titlesAttrs as $i => $attrs ) {
494 $ns = $title->getNamespace();
495 $text = $title->getText();
497 foreach ( $allVariantsName as $variantName ) {
499 if ( $textVariant === $text ) {
503 $variantTitle = Title::makeTitle( $ns, $textVariant );
508 if ( $variantTitle->equals( $parentTitle ) && !$title->hasFragment() ) {
509 $this->internals[$ns][$index][
'selflink'] =
true;
513 $linkBatch->addObj( $variantTitle );
514 $variantMap[$variantTitle->getPrefixedDBkey()][] =
"$ns:$index";
521 foreach (
$output->getCategoryLinks() as $category ) {
522 $categoryTitle = Title::makeTitleSafe(
NS_CATEGORY, $category );
523 $linkBatch->addObj( $categoryTitle );
524 $variants = $this->parent->getContentLanguage()->autoConvertToAllVariants( $category );
525 foreach ( $variants as $variant ) {
526 if ( $variant !== $category ) {
527 $variantTitle = Title::makeTitleSafe(
NS_CATEGORY, $variant );
528 if (
is_null( $variantTitle ) ) {
531 $linkBatch->addObj( $variantTitle );
537 if ( !$linkBatch->isEmpty() ) {
541 LinkCache::getSelectFields(),
542 [
'page_namespace',
'page_title' ]
545 $varRes =
$dbr->select(
'page',
547 $linkBatch->constructSet(
'page',
$dbr ),
551 $linkcolour_ids = [];
555 foreach ( $varRes as
$s ) {
556 $variantTitle = Title::makeTitle(
$s->page_namespace,
$s->page_title );
557 $varPdbk = $variantTitle->getPrefixedDBkey();
558 $vardbk = $variantTitle->getDBkey();
561 if (
isset( $variantMap[$varPdbk] ) ) {
562 $holderKeys = $variantMap[
$varPdbk];
563 $linkCache->addGoodLinkObjFromRow( $variantTitle,
$s );
564 $output->addLink( $variantTitle,
$s->page_id );
568 foreach ( $holderKeys as $key ) {
569 list( $ns, $index ) = explode(
':', $key, 2 );
570 $entry =& $this->internals[$ns][$index];
571 $pdbk = $entry[
'pdbk'];
580 $linkcolour_ids[
$s->page_id] =
$pdbk;
585 if (
isset( $categoryMap[$vardbk] ) ) {
586 list( $oldkey, $oldtitle ) = $categoryMap[
$vardbk];
587 if ( !
isset( $varCategories[$oldkey] ) && !$oldtitle->exists() ) {
592 Hooks::run(
'GetLinkColours', [ $linkcolour_ids, &
$colours, $this->parent->getTitle() ] );
595 if ( count( $varCategories ) > 0 ) {
597 $originalCats =
$output->getCategories();
598 foreach ( $originalCats as $cat => $sortkey ) {
601 $newCats[$varCategories[$cat]] =
$sortkey;
606 $output->setCategoryLinks( $newCats );