176 if ( !$this->internals ) {
181 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
182 $output = $this->parent->getOutput();
183 $linkRenderer = $this->parent->getLinkRenderer();
188 ksort( $this->internals );
190 $linkcolour_ids = [];
194 $lb->setCaller( __METHOD__ );
196 foreach ( $this->internals as $ns => $entries ) {
197 foreach ( $entries as [
'title' =>
$title,
'pdbk' => $pdbk ] ) {
200 # Skip invalid entries.
201 # Result will be ugly, but prevents crash.
206 # Check if it's a static known link, e.g. interwiki
207 if (
$title->isAlwaysKnown() ) {
208 $colours[$pdbk] =
'';
210 $colours[$pdbk] =
'new';
212 $id = $linkCache->getGoodLinkID( $pdbk );
214 $colours[$pdbk] = $linkRenderer->getLinkClasses(
$title );
215 $output->addLink(
$title, $id );
216 $linkcolour_ids[$id] = $pdbk;
217 } elseif ( $linkCache->isBadLink( $pdbk ) ) {
218 $colours[$pdbk] =
'new';
220 # Not in the link cache, add it to the query
226 if ( !$lb->isEmpty() ) {
227 $fields = array_merge(
228 LinkCache::getSelectFields(),
229 [
'page_namespace',
'page_title' ]
235 $lb->constructSet(
'page',
$dbr ),
239 # Fetch data and form into an associative array
240 # non-existent = broken
242 $title = Title::makeTitle(
$s->page_namespace,
$s->page_title );
243 $pdbk =
$title->getPrefixedDBkey();
244 $linkCache->addGoodLinkObjFromRow(
$title,
$s );
245 $output->addLink(
$title,
$s->page_id );
246 $colours[$pdbk] = $linkRenderer->getLinkClasses(
$title );
248 $linkcolour_ids[
$s->page_id] = $pdbk;
252 if ( $linkcolour_ids !== [] ) {
254 $this->hookRunner->onGetLinkColours( $linkcolour_ids, $colours, $this->parent->getTitle() );
257 # Do a second query for different language variants of links and categories
258 if ( $this->languageConverter->hasVariants() ) {
262 # Construct search and replace arrays
264 foreach ( $this->internals as $ns => $entries ) {
265 foreach ( $entries as $index => $entry ) {
266 $pdbk = $entry[
'pdbk'];
268 $query = $entry[
'query'] ?? [];
269 $searchkey =
"<!--LINK'\" $ns:$index-->";
270 $displayTextHtml = $entry[
'text'];
271 if ( isset( $entry[
'selflink'] ) ) {
275 if ( $displayTextHtml ===
'' ) {
278 $displayText =
new HtmlArmor( $displayTextHtml );
280 if ( !isset( $colours[$pdbk] ) ) {
281 $colours[$pdbk] =
'new';
283 if ( $colours[$pdbk] ==
'new' ) {
284 $linkCache->addBadLinkObj(
$title );
285 $output->addLink(
$title, 0 );
286 $link = $linkRenderer->makeBrokenLink(
287 $title, $displayText, [], $query
290 $link = $linkRenderer->makePreloadedLink(
291 $title, $displayText, $colours[$pdbk], [], $query
295 $replacePairs[$searchkey] = $link;
300 $text = preg_replace_callback(
301 '/(<!--LINK\'" .*?-->)/',
302 function ( array
$matches ) use ( $replacePairs ) {
347 $output = $this->parent->getOutput();
348 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
349 $titlesToBeConverted =
'';
355 foreach ( $this->internals as $ns => $entries ) {
359 foreach ( $entries as $index => [
'title' =>
$title,
'pdbk' => $pdbk ] ) {
361 if ( !isset( $colours[$pdbk] ) || $colours[$pdbk] ===
'new' ) {
362 $titlesAttrs[] = [ $index,
$title ];
365 $titlesToBeConverted .=
$title->getText() .
"\0";
371 $titlesAllVariants = $this->languageConverter->
372 autoConvertToAllVariants( rtrim( $titlesToBeConverted,
"\0" ) );
373 foreach ( $titlesAllVariants as &$titlesVariant ) {
374 $titlesVariant = explode(
"\0", $titlesVariant );
378 $parentTitle = $this->parent->getTitle();
379 foreach ( $titlesAttrs as $i => [ $index,
$title ] ) {
381 $ns =
$title->getNamespace();
382 $text =
$title->getText();
384 foreach ( $titlesAllVariants as $variantName => $textVariants ) {
385 $textVariant = $textVariants[$i];
386 if ( $textVariant === $text ) {
390 $variantTitle = Title::makeTitle( $ns, $textVariant );
395 if ( $variantTitle->equals( $parentTitle ) && !
$title->hasFragment() ) {
396 $this->internals[$ns][$index][
'selflink'] =
true;
400 $linkBatch->addObj( $variantTitle );
401 $variantMap[$variantTitle->getPrefixedDBkey()][] =
"$ns:$index";
408 foreach ( $output->getCategoryLinks() as $category ) {
409 $categoryTitle = Title::makeTitleSafe(
NS_CATEGORY, $category );
410 $linkBatch->addObj( $categoryTitle );
411 $variants = $this->languageConverter->autoConvertToAllVariants( $category );
412 foreach ( $variants as $variant ) {
413 if ( $variant !== $category ) {
414 $variantTitle = Title::makeTitleSafe(
NS_CATEGORY, $variant );
415 if ( $variantTitle ===
null ) {
418 $linkBatch->addObj( $variantTitle );
419 $categoryMap[$variant] = [ $category, $categoryTitle ];
424 if ( !$linkBatch->isEmpty() ) {
427 $fields = array_merge(
428 LinkCache::getSelectFields(),
429 [
'page_namespace',
'page_title' ]
432 $varRes =
$dbr->select(
'page',
434 $linkBatch->constructSet(
'page',
$dbr ),
438 $linkcolour_ids = [];
439 $linkRenderer = $this->parent->getLinkRenderer();
442 foreach ( $varRes as
$s ) {
443 $variantTitle = Title::makeTitle(
$s->page_namespace,
$s->page_title );
444 $varPdbk = $variantTitle->getPrefixedDBkey();
445 $vardbk = $variantTitle->getDBkey();
448 if ( isset( $variantMap[$varPdbk] ) ) {
449 $holderKeys = $variantMap[$varPdbk];
450 $linkCache->addGoodLinkObjFromRow( $variantTitle,
$s );
451 $output->addLink( $variantTitle,
$s->page_id );
455 foreach ( $holderKeys as $key ) {
456 list( $ns, $index ) = explode(
':', $key, 2 );
457 $entry =& $this->internals[$ns][$index];
458 $pdbk = $entry[
'pdbk'];
460 if ( !isset( $colours[$pdbk] ) || $colours[$pdbk] ===
'new' ) {
462 $entry[
'title'] = $variantTitle;
463 $entry[
'pdbk'] = $varPdbk;
466 $colours[$varPdbk] = $linkRenderer->getLinkClasses( $variantTitle );
467 $linkcolour_ids[
$s->page_id] = $pdbk;
472 if ( isset( $categoryMap[$vardbk] ) ) {
473 list( $oldkey, $oldtitle ) = $categoryMap[$vardbk];
474 if ( !isset( $varCategories[$oldkey] ) && !$oldtitle->exists() ) {
475 $varCategories[$oldkey] = $vardbk;
479 $this->hookRunner->onGetLinkColours( $linkcolour_ids, $colours, $this->parent->getTitle() );
482 if ( $varCategories !== [] ) {
484 $originalCats = $output->getCategories();
485 foreach ( $originalCats as $cat => $sortkey ) {
487 if ( array_key_exists( $cat, $varCategories ) ) {
488 $newCats[$varCategories[$cat]] = $sortkey;
490 $newCats[$cat] = $sortkey;
493 $output->setCategoryLinks( $newCats );