42 unset( $this->
$name );
55 foreach ( $this->internals
as &$nsLinks ) {
56 foreach ( $nsLinks
as &$entry ) {
57 unset( $entry[
'title'] );
63 foreach ( $this->interwikis
as &$entry ) {
64 unset( $entry[
'title'] );
68 return array(
'internals',
'interwikis',
'size' );
75 foreach ( $this->internals
as &$nsLinks ) {
76 foreach ( $nsLinks
as &$entry ) {
83 foreach ( $this->interwikis
as &$entry ) {
94 foreach ( $other->internals
as $ns => $entries ) {
95 $this->size += count( $entries );
96 if ( !isset( $this->internals[$ns] ) ) {
97 $this->internals[$ns] = $entries;
99 $this->internals[$ns] += $entries;
102 $this->interwikis += $other->interwikis;
118 $this->tempIdOffset = $idOffset = $this->parent->nextLinkID();
121 # Renumber internal links
122 foreach ( $other->internals
as $ns => $nsLinks ) {
123 foreach ( $nsLinks
as $key => $entry ) {
124 $newKey = $idOffset + $key;
125 $this->internals[$ns][$newKey] = $entry;
126 $maxId = $newKey > $maxId ? $newKey : $maxId;
129 $texts = preg_replace_callback(
'/(<!--LINK \d+:)(\d+)(-->)/',
130 array( $this,
'mergeForeignCallback' ), $texts );
132 # Renumber interwiki links
133 foreach ( $other->interwikis
as $key => $entry ) {
134 $newKey = $idOffset + $key;
135 $this->interwikis[$newKey] = $entry;
136 $maxId = $newKey > $maxId ? $newKey : $maxId;
138 $texts = preg_replace_callback(
'/(<!--IWLINK )(\d+)(-->)/',
139 array( $this,
'mergeForeignCallback' ), $texts );
141 # Set the parent link ID to be beyond the highest used ID
142 $this->parent->setLinkID( $maxId + 1 );
143 $this->tempIdOffset =
null;
161 while ( $pos < strlen( $text ) ) {
162 if ( !preg_match(
'/<!--LINK (\d+):(\d+)-->/',
163 $text, $m, PREG_OFFSET_CAPTURE, $pos )
169 $sub->internals[$ns][$key] = $this->internals[$ns][$key];
170 $pos = $m[0][1] + strlen( $m[0][0] );
175 while ( $pos < strlen( $text ) ) {
176 if ( !preg_match(
'/<!--IWLINK (\d+)-->/', $text, $m, PREG_OFFSET_CAPTURE, $pos ) ) {
180 $sub->interwikis[$key] = $this->interwikis[$key];
181 $pos = $m[0][1] + strlen( $m[0][0] );
191 global $wgLinkHolderBatchSize;
192 return $this->size > $wgLinkHolderBatchSize;
200 $this->internals =
array();
201 $this->interwikis =
array();
220 if ( !is_object( $nt ) ) {
222 $retVal =
"<!-- ERROR -->{$prefix}{$text}{$trail}";
224 # Separate the link trail from the rest of the link
229 'text' => $prefix . $text . $inside,
230 'pdbk' => $nt->getPrefixedDBkey(),
236 if ( $nt->isExternal() ) {
238 $key = $this->parent->nextLinkID();
239 $this->interwikis[$key] = $entry;
240 $retVal =
"<!--IWLINK $key-->{$trail}";
242 $key = $this->parent->nextLinkID();
243 $ns = $nt->getNamespace();
244 $this->internals[$ns][$key] = $entry;
245 $retVal =
"<!--LINK $ns:$key-->{$trail}";
272 if ( !$this->internals ) {
281 $output = $this->parent->getOutput();
285 $threshold = $this->parent->getOptions()->getStubThreshold();
288 ksort( $this->internals );
290 $linkcolour_ids =
array();
294 foreach ( $this->internals
as $ns => $entries ) {
295 foreach ( $entries
as $entry ) {
297 $pdbk = $entry[
'pdbk'];
299 # Skip invalid entries.
300 # Result will be ugly, but prevents crash.
301 if ( is_null(
$title ) ) {
305 # Check if it's a static known link, e.g. interwiki
306 if (
$title->isAlwaysKnown() ) {
310 } elseif ( ( $id = $linkCache->getGoodLinkID( $pdbk ) ) != 0 ) {
313 $linkcolour_ids[$id] = $pdbk;
314 } elseif ( $linkCache->isBadLink( $pdbk ) ) {
317 # Not in the link cache, add it to the query
325 $where[] =
$dbr->makeList(
327 'page_namespace' => $ns,
328 'page_title' => $pages,
336 array(
'page_id',
'page_namespace',
'page_title',
'page_is_redirect',
'page_len',
'page_latest' ),
341 # Fetch data and form into an associative array
342 # non-existent = broken
345 $pdbk =
$title->getPrefixedDBkey();
346 $linkCache->addGoodLinkObjFromRow(
$title,
$s );
348 # @todo FIXME: Convoluted data flow
349 # The redirect status and length is passed to getLinkColour via the LinkCache
350 # Use formal parameters instead
353 $linkcolour_ids[
$s->page_id] = $pdbk;
357 if ( count( $linkcolour_ids ) ) {
363 # Do a second query for different language variants of links and categories
368 # Construct search and replace arrays
370 $replacePairs =
array();
371 foreach ( $this->internals
as $ns => $entries ) {
372 foreach ( $entries
as $index => $entry ) {
373 $pdbk = $entry[
'pdbk'];
375 $query = isset( $entry[
'query'] ) ? $entry[
'query'] :
array();
377 $searchkey =
"<!--LINK $key-->";
378 $displayText = $entry[
'text'];
379 if ( isset( $entry[
'selflink'] ) ) {
383 if ( $displayText ===
'' ) {
391 $linkCache->addBadLinkObj(
$title );
409 $text = preg_replace_callback(
410 '/(<!--LINK .*?-->)/',
423 if ( empty( $this->interwikis ) ) {
428 # Make interwiki link HTML
429 $output = $this->parent->getOutput();
430 $replacePairs =
array();
431 foreach ( $this->interwikis
as $key =>
$link ) {
437 $text = preg_replace_callback(
438 '/<!--IWLINK (.*?)-->/',
450 $variantMap =
array();
451 $output = $this->parent->getOutput();
453 $threshold = $this->parent->getOptions()->getStubThreshold();
454 $titlesToBeConverted =
'';
455 $titlesAttrs =
array();
460 foreach ( $this->internals
as $ns => $entries ) {
464 foreach ( $entries
as $index => $entry ) {
465 $pdbk = $entry[
'pdbk'];
468 $titlesAttrs[] =
array( $index, $entry[
'title'] );
471 $titlesToBeConverted .= $entry[
'title']->getText() .
"\0";
477 $titlesAllVariants =
$wgContLang->autoConvertToAllVariants( rtrim( $titlesToBeConverted,
"\0" ) );
478 $allVariantsName = array_keys( $titlesAllVariants );
479 foreach ( $titlesAllVariants
as &$titlesVariant ) {
480 $titlesVariant = explode(
"\0", $titlesVariant );
484 $parentTitle = $this->parent->getTitle();
485 foreach ( $titlesAttrs
as $i => $attrs ) {
487 $ns =
$title->getNamespace();
488 $text =
$title->getText();
490 foreach ( $allVariantsName
as $variantName ) {
491 $textVariant = $titlesAllVariants[$variantName][$i];
492 if ( $textVariant === $text ) {
497 if ( is_null( $variantTitle ) ) {
504 if ( $variantTitle->equals( $parentTitle ) && !
$title->hasFragment() ) {
505 $this->internals[$ns][$index][
'selflink'] =
true;
509 $linkBatch->addObj( $variantTitle );
510 $variantMap[$variantTitle->getPrefixedDBkey()][] =
"$ns:$index";
515 $categoryMap =
array();
516 $varCategories =
array();
517 foreach (
$output->getCategoryLinks()
as $category ) {
519 $linkBatch->addObj( $categoryTitle );
520 $variants =
$wgContLang->autoConvertToAllVariants( $category );
521 foreach ( $variants
as $variant ) {
522 if ( $variant !== $category ) {
524 if ( is_null( $variantTitle ) ) {
527 $linkBatch->addObj( $variantTitle );
528 $categoryMap[$variant] =
array( $category, $categoryTitle );
533 if ( !$linkBatch->isEmpty() ) {
536 $varRes =
$dbr->select(
'page',
537 array(
'page_id',
'page_namespace',
'page_title',
'page_is_redirect',
'page_len',
'page_latest' ),
538 $linkBatch->constructSet(
'page',
$dbr ),
542 $linkcolour_ids =
array();
545 foreach ( $varRes
as $s ) {
548 $varPdbk = $variantTitle->getPrefixedDBkey();
549 $vardbk = $variantTitle->getDBkey();
551 $holderKeys =
array();
552 if ( isset( $variantMap[$varPdbk] ) ) {
553 $holderKeys = $variantMap[$varPdbk];
554 $linkCache->addGoodLinkObjFromRow( $variantTitle,
$s );
555 $output->addLink( $variantTitle,
$s->page_id );
559 foreach ( $holderKeys
as $key ) {
560 list( $ns, $index ) = explode(
':', $key, 2 );
561 $entry =& $this->internals[$ns][$index];
562 $pdbk = $entry[
'pdbk'];
566 $entry[
'title'] = $variantTitle;
567 $entry[
'pdbk'] = $varPdbk;
570 # @todo FIXME: Convoluted data flow
571 # The redirect status and length is passed to getLinkColour via the LinkCache
572 # Use formal parameters instead
574 $linkcolour_ids[
$s->page_id] = $pdbk;
579 if ( isset( $categoryMap[$vardbk] ) ) {
580 list( $oldkey, $oldtitle ) = $categoryMap[$vardbk];
581 if ( !isset( $varCategories[$oldkey] ) && !$oldtitle->exists() ) {
582 $varCategories[$oldkey] = $vardbk;
589 if ( count( $varCategories ) > 0 ) {
591 $originalCats =
$output->getCategories();
592 foreach ( $originalCats
as $cat => $sortkey ) {
594 if ( array_key_exists( $cat, $varCategories ) ) {
595 $newCats[$varCategories[$cat]] = $sortkey;
597 $newCats[$cat] = $sortkey;
600 $output->setCategoryLinks( $newCats );
615 $text = preg_replace_callback(
616 '/<!--(LINK|IWLINK) (.*?)-->/',
617 array( &$this,
'replaceTextCallback' ),
634 if (
$type ==
'LINK' ) {
635 list( $ns, $index ) = explode(
':', $key, 2 );
636 if ( isset( $this->internals[$ns][$index][
'text'] ) ) {
637 return $this->internals[$ns][$index][
'text'];
639 } elseif (
$type ==
'IWLINK' ) {
640 if ( isset( $this->interwikis[$key][
'text'] ) ) {
641 return $this->interwikis[$key][
'text'];