126 $this->tempIdOffset = $idOffset = $this->parent->nextLinkID();
129 # Renumber internal links
130 foreach ( $other->internals as $ns => $nsLinks ) {
131 foreach ( $nsLinks as $key => $entry ) {
132 $newKey = $idOffset + $key;
133 $this->internals[$ns][$newKey] = $entry;
134 $maxId = $newKey > $maxId ? $newKey : $maxId;
137 $texts = preg_replace_callback(
'/(<!--LINK\'" \d+:)(\d+)(-->)/',
138 [ $this,
'mergeForeignCallback' ], $texts );
140 # Renumber interwiki links
141 foreach ( $other->interwikis as $key => $entry ) {
142 $newKey = $idOffset + $key;
143 $this->interwikis[$newKey] = $entry;
144 $maxId = $newKey > $maxId ? $newKey : $maxId;
146 $texts = preg_replace_callback(
'/(<!--IWLINK\'" )(\d+)(-->)/',
147 [ $this,
'mergeForeignCallback' ], $texts );
149 # Set the parent link ID to be beyond the highest used ID
150 $this->parent->setLinkID( $maxId + 1 );
151 $this->tempIdOffset =
null;
174 while ( $pos < strlen( $text ) ) {
175 if ( !preg_match(
'/<!--LINK\'" (\d+):(\d+)-->/',
176 $text, $m, PREG_OFFSET_CAPTURE, $pos )
182 $sub->internals[$ns][$key] = $this->internals[$ns][$key];
183 $pos = $m[0][1] + strlen( $m[0][0] );
188 while ( $pos < strlen( $text ) ) {
189 if ( !preg_match(
'/<!--IWLINK\'" (\d+)-->/', $text, $m, PREG_OFFSET_CAPTURE, $pos ) ) {
193 $sub->interwikis[$key] = $this->interwikis[$key];
194 $pos = $m[0][1] + strlen( $m[0][0] );
279 if ( !$this->internals ) {
286 $linkCache = LinkCache::singleton();
287 $output = $this->parent->getOutput();
293 ksort( $this->internals );
295 $linkcolour_ids = [];
299 $lb->setCaller( __METHOD__ );
301 foreach ( $this->internals as $ns => $entries ) {
302 foreach ( $entries as $entry ) {
304 $title = $entry[
'title'];
305 $pdbk = $entry[
'pdbk'];
307 # Skip invalid entries.
308 # Result will be ugly, but prevents crash.
309 if ( is_null( $title ) ) {
313 # Check if it's a static known link, e.g. interwiki
314 if ( $title->isAlwaysKnown() ) {
319 $id = $linkCache->getGoodLinkID( $pdbk );
322 $output->addLink( $title, $id );
323 $linkcolour_ids[$id] = $pdbk;
324 } elseif ( $linkCache->isBadLink( $pdbk ) ) {
327 # Not in the link cache, add it to the query
328 $lb->addObj( $title );
333 if ( !$lb->isEmpty() ) {
334 $fields = array_merge(
335 LinkCache::getSelectFields(),
336 [
'page_namespace',
'page_title' ]
342 $lb->constructSet(
'page',
$dbr ),
346 # Fetch data and form into an associative array
347 # non-existent = broken
349 $title = Title::makeTitle(
$s->page_namespace,
$s->page_title );
350 $pdbk = $title->getPrefixedDBkey();
351 $linkCache->addGoodLinkObjFromRow( $title,
$s );
355 $linkcolour_ids[
$s->page_id] = $pdbk;
359 if ( count( $linkcolour_ids ) ) {
361 Hooks::run(
'GetLinkColours', [ $linkcolour_ids, &
$colours ] );
364 # Do a second query for different language variants of links and categories
369 # Construct search and replace arrays
371 foreach ( $this->internals as $ns => $entries ) {
372 foreach ( $entries as $index => $entry ) {
373 $pdbk = $entry[
'pdbk'];
374 $title = $entry[
'title'];
375 $query = isset( $entry[
'query'] ) ? $entry[
'query'] : [];
377 $searchkey =
"<!--LINK'\" $key-->";
378 $displayText = $entry[
'text'];
379 if ( isset( $entry[
'selflink'] ) ) {
383 if ( $displayText ===
'' ) {
386 $displayText =
new HtmlArmor( $displayText );
393 $linkCache->addBadLinkObj( $title );
404 $replacePairs[$searchkey] =
$link;
410 $text = preg_replace_callback(
411 '/(<!--LINK\'" .*?-->)/',
453 $output = $this->parent->getOutput();
454 $linkCache = LinkCache::singleton();
455 $titlesToBeConverted =
'';
461 foreach ( $this->internals as $ns => $entries ) {
465 foreach ( $entries as $index => $entry ) {
466 $pdbk = $entry[
'pdbk'];
469 $titlesAttrs[] = [ $index, $entry[
'title'] ];
472 $titlesToBeConverted .= $entry[
'title']->getText() .
"\0";
478 $titlesAllVariants =
$wgContLang->autoConvertToAllVariants( rtrim( $titlesToBeConverted,
"\0" ) );
479 $allVariantsName = array_keys( $titlesAllVariants );
480 foreach ( $titlesAllVariants as &$titlesVariant ) {
481 $titlesVariant = explode(
"\0", $titlesVariant );
485 $parentTitle = $this->parent->getTitle();
486 foreach ( $titlesAttrs as $i => $attrs ) {
488 list( $index, $title ) = $attrs;
489 $ns = $title->getNamespace();
490 $text = $title->getText();
492 foreach ( $allVariantsName as $variantName ) {
493 $textVariant = $titlesAllVariants[$variantName][$i];
494 if ( $textVariant === $text ) {
498 $variantTitle = Title::makeTitle( $ns, $textVariant );
503 if ( $variantTitle->equals( $parentTitle ) && !$title->hasFragment() ) {
504 $this->internals[$ns][$index][
'selflink'] =
true;
508 $linkBatch->addObj( $variantTitle );
509 $variantMap[$variantTitle->getPrefixedDBkey()][] =
"$ns:$index";
516 foreach (
$output->getCategoryLinks() as $category ) {
517 $categoryTitle = Title::makeTitleSafe(
NS_CATEGORY, $category );
518 $linkBatch->addObj( $categoryTitle );
519 $variants =
$wgContLang->autoConvertToAllVariants( $category );
520 foreach ( $variants as $variant ) {
521 if ( $variant !== $category ) {
522 $variantTitle = Title::makeTitleSafe(
NS_CATEGORY, $variant );
523 if ( is_null( $variantTitle ) ) {
526 $linkBatch->addObj( $variantTitle );
527 $categoryMap[$variant] = [ $category, $categoryTitle ];
532 if ( !$linkBatch->isEmpty() ) {
535 $fields = array_merge(
536 LinkCache::getSelectFields(),
537 [
'page_namespace',
'page_title' ]
540 $varRes =
$dbr->select(
'page',
542 $linkBatch->constructSet(
'page',
$dbr ),
546 $linkcolour_ids = [];
550 foreach ( $varRes as
$s ) {
551 $variantTitle = Title::makeTitle(
$s->page_namespace,
$s->page_title );
552 $varPdbk = $variantTitle->getPrefixedDBkey();
553 $vardbk = $variantTitle->getDBkey();
556 if ( isset( $variantMap[$varPdbk] ) ) {
557 $holderKeys = $variantMap[$varPdbk];
558 $linkCache->addGoodLinkObjFromRow( $variantTitle,
$s );
559 $output->addLink( $variantTitle,
$s->page_id );
563 foreach ( $holderKeys as $key ) {
564 list( $ns, $index ) = explode(
':', $key, 2 );
565 $entry =& $this->internals[$ns][$index];
566 $pdbk = $entry[
'pdbk'];
570 $entry[
'title'] = $variantTitle;
571 $entry[
'pdbk'] = $varPdbk;
575 $linkcolour_ids[
$s->page_id] = $pdbk;
580 if ( isset( $categoryMap[$vardbk] ) ) {
581 list( $oldkey, $oldtitle ) = $categoryMap[$vardbk];
582 if ( !isset( $varCategories[$oldkey] ) && !$oldtitle->exists() ) {
583 $varCategories[$oldkey] = $vardbk;
587 Hooks::run(
'GetLinkColours', [ $linkcolour_ids, &
$colours ] );
590 if ( count( $varCategories ) > 0 ) {
592 $originalCats =
$output->getCategories();
593 foreach ( $originalCats as $cat => $sortkey ) {
595 if ( array_key_exists( $cat, $varCategories ) ) {
596 $newCats[$varCategories[$cat]] = $sortkey;
598 $newCats[$cat] = $sortkey;
601 $output->setCategoryLinks( $newCats );