169 if ( !$this->internals ) {
174 $services = MediaWikiServices::getInstance();
175 $linkCache = $services->getLinkCache();
176 $output = $this->parent->getOutput();
177 $linkRenderer = $this->parent->getLinkRenderer();
182 ksort( $this->internals );
187 $linkBatchFactory = $services->getLinkBatchFactory();
188 $lb = $linkBatchFactory->newLinkBatch();
189 $lb->setCaller( __METHOD__ );
191 foreach ( $this->internals as $ns => $entries ) {
192 foreach ( $entries as [
'title' =>
$title,
'pdbk' => $pdbk ] ) {
194 # Check if it's a static known link, e.g. interwiki
195 if (
$title->isAlwaysKnown() ) {
196 $classes[$pdbk] =
'';
198 $classes[$pdbk] =
'new';
200 $id = $linkCache->getGoodLinkID( $pdbk );
202 $classes[$pdbk] = $linkRenderer->getLinkClasses(
$title );
203 $output->addLink(
$title, $id );
204 $pagemap[$id] = $pdbk;
205 } elseif ( $linkCache->isBadLink( $pdbk ) ) {
206 $classes[$pdbk] =
'new';
208 # Not in the link cache, add it to the query
214 if ( !$lb->isEmpty() ) {
215 $res =
$dbr->newSelectQueryBuilder()
216 ->select( LinkCache::getSelectFields() )
218 ->where( [ $lb->constructSet(
'page',
$dbr ) ] )
219 ->caller( __METHOD__ )
222 # Fetch data and form into an associative array
223 # non-existent = broken
224 foreach (
$res as $s ) {
225 $title = Title::makeTitle( $s->page_namespace, $s->page_title );
226 $pdbk =
$title->getPrefixedDBkey();
227 $linkCache->addGoodLinkObjFromRow(
$title, $s );
228 $output->addLink(
$title, $s->page_id );
229 $classes[$pdbk] = $linkRenderer->getLinkClasses(
$title );
231 $pagemap[$s->page_id] = $pdbk;
235 if ( $pagemap !== [] ) {
237 $this->hookRunner->onGetLinkColours( $pagemap, $classes, $this->parent->getTitle() );
240 # Do a second query for different language variants of links and categories
241 if ( $this->languageConverter->hasVariants() ) {
245 # Construct search and replace arrays
247 foreach ( $this->internals as $ns => $entries ) {
248 foreach ( $entries as $index => $entry ) {
249 $pdbk = $entry[
'pdbk'];
251 $query = $entry[
'query'] ?? [];
252 $searchkey =
"$ns:$index";
253 $displayTextHtml = $entry[
'text'];
254 if ( isset( $entry[
'selflink'] ) ) {
255 $replacePairs[$searchkey] = Linker::makeSelfLinkObj(
$title, $displayTextHtml, $query );
259 $displayText = $displayTextHtml ===
'' ? null :
new HtmlArmor( $displayTextHtml );
260 if ( !isset( $classes[$pdbk] ) ) {
261 $classes[$pdbk] =
'new';
263 if ( $classes[$pdbk] ===
'new' ) {
264 $linkCache->addBadLinkObj(
$title );
265 $output->addLink(
$title, 0 );
266 $link = $linkRenderer->makeBrokenLink(
267 $title, $displayText, [], $query
270 $link = $linkRenderer->makePreloadedLink(
271 $title, $displayText, $classes[$pdbk], [], $query
275 $replacePairs[$searchkey] = $link;
280 $text = preg_replace_callback(
281 '/<!--LINK\'" (-?[\d+:]+)-->/',
282 static function ( array
$matches ) use ( $replacePairs ) {
321 $linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
322 $linkBatch = $linkBatchFactory->newLinkBatch();
324 $output = $this->parent->getOutput();
325 $titlesToBeConverted =
'';
331 foreach ( $this->internals as $ns => $entries ) {
335 foreach ( $entries as $index => [
'title' =>
$title,
'pdbk' => $pdbk ] ) {
337 if ( !isset( $classes[$pdbk] ) || $classes[$pdbk] ===
'new' ) {
338 $titlesAttrs[] = [ $index,
$title ];
341 $titlesToBeConverted .=
$title->getText() .
"\0";
347 $titlesAllVariants = $this->languageConverter->
348 autoConvertToAllVariants( rtrim( $titlesToBeConverted,
"\0" ) );
349 foreach ( $titlesAllVariants as &$titlesVariant ) {
350 $titlesVariant = explode(
"\0", $titlesVariant );
354 $parentTitle = $this->parent->getTitle();
355 foreach ( $titlesAttrs as $i => [ $index,
$title ] ) {
357 $ns =
$title->getNamespace();
358 $text =
$title->getText();
360 foreach ( $titlesAllVariants as $textVariants ) {
361 $textVariant = $textVariants[$i];
362 if ( $textVariant === $text ) {
366 $variantTitle = Title::makeTitle( $ns, $textVariant );
371 if ( $variantTitle->equals( $parentTitle ) && !
$title->hasFragment() ) {
372 $this->internals[$ns][$index][
'selflink'] =
true;
376 $linkBatch->addObj( $variantTitle );
377 $variantMap[$variantTitle->getPrefixedDBkey()][] =
"$ns:$index";
383 foreach ( $output->getCategoryNames() as $category ) {
384 $categoryTitle = Title::makeTitleSafe(
NS_CATEGORY, $category );
385 $linkBatch->addObj( $categoryTitle );
386 $variants = $this->languageConverter->autoConvertToAllVariants( $category );
387 foreach ( $variants as $variant ) {
388 if ( $variant !== $category ) {
389 $variantTitle = Title::makeTitleSafe(
NS_CATEGORY, $variant );
390 if ( $variantTitle ) {
391 $linkBatch->addObj( $variantTitle );
392 $categoryMap[$variant] = [ $category, $categoryTitle ];
398 if ( $linkBatch->isEmpty() ) {
405 $varRes =
$dbr->newSelectQueryBuilder()
406 ->select( LinkCache::getSelectFields() )
408 ->where( [ $linkBatch->constructSet(
'page',
$dbr ) ] )
409 ->caller( __METHOD__ )
414 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
415 $linkRenderer = $this->parent->getLinkRenderer();
418 foreach ( $varRes as $s ) {
419 $variantTitle = Title::makeTitle( $s->page_namespace, $s->page_title );
420 $varPdbk = $variantTitle->getPrefixedDBkey();
422 if ( !isset( $variantMap[$varPdbk] ) ) {
426 $linkCache->addGoodLinkObjFromRow( $variantTitle, $s );
427 $output->addLink( $variantTitle, $s->page_id );
430 foreach ( $variantMap[$varPdbk] as $key ) {
431 [ $ns, $index ] = explode(
':', $key, 2 );
432 $entry =& $this->internals[(int)$ns][(
int)$index];
433 $pdbk = $entry[
'pdbk'];
435 if ( !isset( $classes[$pdbk] ) || $classes[$pdbk] ===
'new' ) {
437 $entry[
'title'] = $variantTitle;
438 $entry[
'pdbk'] = $varPdbk;
441 $classes[$varPdbk] = $linkRenderer->getLinkClasses( $variantTitle );
442 $pagemap[$s->page_id] = $pdbk;
447 $vardbk = $variantTitle->getDBkey();
448 if ( isset( $categoryMap[$vardbk] ) ) {
449 [ $oldkey, $oldtitle ] = $categoryMap[$vardbk];
450 if ( !isset( $varCategories[$oldkey] ) && !$oldtitle->exists() ) {
451 $varCategories[$oldkey] = $vardbk;
455 $this->hookRunner->onGetLinkColours( $pagemap, $classes, $this->parent->getTitle() );
458 if ( $varCategories !== [] ) {
460 $originalCats = $output->getCategories();
461 foreach ( $originalCats as $cat => $sortkey ) {
463 $newCats[$varCategories[$cat] ?? $cat] = $sortkey;
465 $output->setCategories( $newCats );