176 if ( !$this->internals ) {
181 $services = MediaWikiServices::getInstance();
182 $linkCache = $services->getLinkCache();
183 $output = $this->parent->getOutput();
184 $linkRenderer = $this->parent->getLinkRenderer();
189 ksort( $this->internals );
194 $linkBatchFactory = $services->getLinkBatchFactory();
195 $lb = $linkBatchFactory->newLinkBatch();
196 $lb->setCaller( __METHOD__ );
198 foreach ( $this->internals as $ns => $entries ) {
199 foreach ( $entries as [
'title' =>
$title,
'pdbk' => $pdbk ] ) {
202 # Skip invalid entries.
203 # Result will be ugly, but prevents crash.
208 # Check if it's a static known link, e.g. interwiki
209 if (
$title->isAlwaysKnown() ) {
210 $classes[$pdbk] =
'';
212 $classes[$pdbk] =
'new';
214 $id = $linkCache->getGoodLinkID( $pdbk );
216 $classes[$pdbk] = $linkRenderer->getLinkClasses(
$title );
217 $output->addLink(
$title, $id );
218 $pagemap[$id] = $pdbk;
219 } elseif ( $linkCache->isBadLink( $pdbk ) ) {
220 $classes[$pdbk] =
'new';
222 # Not in the link cache, add it to the query
228 if ( !$lb->isEmpty() ) {
229 $fields = array_merge(
230 LinkCache::getSelectFields(),
231 [
'page_namespace',
'page_title' ]
237 $lb->constructSet(
'page',
$dbr ),
241 # Fetch data and form into an associative array
242 # non-existent = broken
244 $title = Title::makeTitle(
$s->page_namespace,
$s->page_title );
245 $pdbk =
$title->getPrefixedDBkey();
246 $linkCache->addGoodLinkObjFromRow(
$title,
$s );
247 $output->addLink(
$title,
$s->page_id );
248 $classes[$pdbk] = $linkRenderer->getLinkClasses(
$title );
250 $pagemap[
$s->page_id] = $pdbk;
254 if ( $pagemap !== [] ) {
256 $this->hookRunner->onGetLinkColours( $pagemap, $classes, $this->parent->getTitle() );
259 # Do a second query for different language variants of links and categories
260 if ( $this->languageConverter->hasVariants() ) {
264 # Construct search and replace arrays
266 foreach ( $this->internals as $ns => $entries ) {
267 foreach ( $entries as $index => $entry ) {
268 $pdbk = $entry[
'pdbk'];
270 $query = $entry[
'query'] ?? [];
271 $searchkey =
"<!--LINK'\" $ns:$index-->";
272 $displayTextHtml = $entry[
'text'];
273 if ( isset( $entry[
'selflink'] ) ) {
277 if ( $displayTextHtml ===
'' ) {
280 $displayText =
new HtmlArmor( $displayTextHtml );
282 if ( !isset( $classes[$pdbk] ) ) {
283 $classes[$pdbk] =
'new';
285 if ( $classes[$pdbk] ==
'new' ) {
286 $linkCache->addBadLinkObj(
$title );
287 $output->addLink(
$title, 0 );
288 $link = $linkRenderer->makeBrokenLink(
289 $title, $displayText, [], $query
292 $link = $linkRenderer->makePreloadedLink(
293 $title, $displayText, $classes[$pdbk], [], $query
297 $replacePairs[$searchkey] = $link;
302 $text = preg_replace_callback(
303 '/(<!--LINK\'" .*?-->)/',
304 static function ( array
$matches ) use ( $replacePairs ) {
346 $linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
347 $linkBatch = $linkBatchFactory->newLinkBatch();
349 $output = $this->parent->getOutput();
350 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
351 $titlesToBeConverted =
'';
357 foreach ( $this->internals as $ns => $entries ) {
361 foreach ( $entries as $index => [
'title' =>
$title,
'pdbk' => $pdbk ] ) {
363 if ( !isset( $classes[$pdbk] ) || $classes[$pdbk] ===
'new' ) {
364 $titlesAttrs[] = [ $index,
$title ];
367 $titlesToBeConverted .=
$title->getText() .
"\0";
373 $titlesAllVariants = $this->languageConverter->
374 autoConvertToAllVariants( rtrim( $titlesToBeConverted,
"\0" ) );
375 foreach ( $titlesAllVariants as &$titlesVariant ) {
376 $titlesVariant = explode(
"\0", $titlesVariant );
380 $parentTitle = $this->parent->getTitle();
381 foreach ( $titlesAttrs as $i => [ $index,
$title ] ) {
383 $ns =
$title->getNamespace();
384 $text =
$title->getText();
386 foreach ( $titlesAllVariants as $variantName => $textVariants ) {
387 $textVariant = $textVariants[$i];
388 if ( $textVariant === $text ) {
392 $variantTitle = Title::makeTitle( $ns, $textVariant );
397 if ( $variantTitle->equals( $parentTitle ) && !
$title->hasFragment() ) {
398 $this->internals[$ns][$index][
'selflink'] =
true;
402 $linkBatch->addObj( $variantTitle );
403 $variantMap[$variantTitle->getPrefixedDBkey()][] =
"$ns:$index";
410 foreach ( $output->getCategoryLinks() as $category ) {
411 $categoryTitle = Title::makeTitleSafe(
NS_CATEGORY, $category );
412 $linkBatch->addObj( $categoryTitle );
413 $variants = $this->languageConverter->autoConvertToAllVariants( $category );
414 foreach ( $variants as $variant ) {
415 if ( $variant !== $category ) {
416 $variantTitle = Title::makeTitleSafe(
NS_CATEGORY, $variant );
417 if ( $variantTitle ===
null ) {
420 $linkBatch->addObj( $variantTitle );
421 $categoryMap[$variant] = [ $category, $categoryTitle ];
426 if ( !$linkBatch->isEmpty() ) {
429 $fields = array_merge(
430 LinkCache::getSelectFields(),
431 [
'page_namespace',
'page_title' ]
434 $varRes =
$dbr->select(
'page',
436 $linkBatch->constructSet(
'page',
$dbr ),
441 $linkRenderer = $this->parent->getLinkRenderer();
444 foreach ( $varRes as
$s ) {
445 $variantTitle = Title::makeTitle(
$s->page_namespace,
$s->page_title );
446 $varPdbk = $variantTitle->getPrefixedDBkey();
447 $vardbk = $variantTitle->getDBkey();
450 if ( isset( $variantMap[$varPdbk] ) ) {
451 $holderKeys = $variantMap[$varPdbk];
452 $linkCache->addGoodLinkObjFromRow( $variantTitle,
$s );
453 $output->addLink( $variantTitle,
$s->page_id );
457 foreach ( $holderKeys as $key ) {
458 list( $ns, $index ) = explode(
':', $key, 2 );
459 $entry =& $this->internals[$ns][$index];
460 $pdbk = $entry[
'pdbk'];
462 if ( !isset( $classes[$pdbk] ) || $classes[$pdbk] ===
'new' ) {
464 $entry[
'title'] = $variantTitle;
465 $entry[
'pdbk'] = $varPdbk;
468 $classes[$varPdbk] = $linkRenderer->getLinkClasses( $variantTitle );
469 $pagemap[
$s->page_id] = $pdbk;
474 if ( isset( $categoryMap[$vardbk] ) ) {
475 list( $oldkey, $oldtitle ) = $categoryMap[$vardbk];
476 if ( !isset( $varCategories[$oldkey] ) && !$oldtitle->exists() ) {
477 $varCategories[$oldkey] = $vardbk;
481 $this->hookRunner->onGetLinkColours( $pagemap, $classes, $this->parent->getTitle() );
484 if ( $varCategories !== [] ) {
486 $originalCats = $output->getCategories();
487 foreach ( $originalCats as $cat => $sortkey ) {
489 $newCats[$varCategories[$cat] ?? $cat] = $sortkey;
491 $output->setCategoryLinks( $newCats );