summaryrefslogtreecommitdiff
path: root/includes/parser/LinkHolderArray.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/parser/LinkHolderArray.php')
-rw-r--r--includes/parser/LinkHolderArray.php216
1 files changed, 118 insertions, 98 deletions
diff --git a/includes/parser/LinkHolderArray.php b/includes/parser/LinkHolderArray.php
index 49b2d333..27ff9e7d 100644
--- a/includes/parser/LinkHolderArray.php
+++ b/includes/parser/LinkHolderArray.php
@@ -281,88 +281,90 @@ class LinkHolderArray {
$linkCache = LinkCache::singleton();
$output = $this->parent->getOutput();
- wfProfileIn( __METHOD__ . '-check' );
- $dbr = wfGetDB( DB_SLAVE );
- $threshold = $this->parent->getOptions()->getStubThreshold();
+ if( $linkCache->useDatabase() ) {
+ wfProfileIn( __METHOD__ . '-check' );
+ $dbr = wfGetDB( DB_SLAVE );
+ $threshold = $this->parent->getOptions()->getStubThreshold();
- # Sort by namespace
- ksort( $this->internals );
+ # Sort by namespace
+ ksort( $this->internals );
- $linkcolour_ids = array();
+ $linkcolour_ids = array();
- # Generate query
- $queries = array();
- foreach ( $this->internals as $ns => $entries ) {
- foreach ( $entries as $entry ) {
- $title = $entry['title'];
- $pdbk = $entry['pdbk'];
+ # Generate query
+ $queries = array();
+ foreach ( $this->internals as $ns => $entries ) {
+ foreach ( $entries as $entry ) {
+ $title = $entry['title'];
+ $pdbk = $entry['pdbk'];
- # Skip invalid entries.
- # Result will be ugly, but prevents crash.
- if ( is_null( $title ) ) {
- continue;
- }
+ # Skip invalid entries.
+ # Result will be ugly, but prevents crash.
+ if ( is_null( $title ) ) {
+ continue;
+ }
- # Check if it's a static known link, e.g. interwiki
- if ( $title->isAlwaysKnown() ) {
- $colours[$pdbk] = '';
- } elseif ( $ns == NS_SPECIAL ) {
- $colours[$pdbk] = 'new';
- } elseif ( ( $id = $linkCache->getGoodLinkID( $pdbk ) ) != 0 ) {
- $colours[$pdbk] = Linker::getLinkColour( $title, $threshold );
- $output->addLink( $title, $id );
- $linkcolour_ids[$id] = $pdbk;
- } elseif ( $linkCache->isBadLink( $pdbk ) ) {
- $colours[$pdbk] = 'new';
- } else {
- # Not in the link cache, add it to the query
- $queries[$ns][] = $title->getDBkey();
+ # Check if it's a static known link, e.g. interwiki
+ if ( $title->isAlwaysKnown() ) {
+ $colours[$pdbk] = '';
+ } elseif ( $ns == NS_SPECIAL ) {
+ $colours[$pdbk] = 'new';
+ } elseif ( ( $id = $linkCache->getGoodLinkID( $pdbk ) ) != 0 ) {
+ $colours[$pdbk] = Linker::getLinkColour( $title, $threshold );
+ $output->addLink( $title, $id );
+ $linkcolour_ids[$id] = $pdbk;
+ } elseif ( $linkCache->isBadLink( $pdbk ) ) {
+ $colours[$pdbk] = 'new';
+ } else {
+ # Not in the link cache, add it to the query
+ $queries[$ns][] = $title->getDBkey();
+ }
}
}
- }
- if ( $queries ) {
- $where = array();
- foreach( $queries as $ns => $pages ) {
- $where[] = $dbr->makeList(
- array(
- 'page_namespace' => $ns,
- 'page_title' => $pages,
- ),
- LIST_AND
- );
- }
+ if ( $queries ) {
+ $where = array();
+ foreach ( $queries as $ns => $pages ) {
+ $where[] = $dbr->makeList(
+ array(
+ 'page_namespace' => $ns,
+ 'page_title' => $pages,
+ ),
+ LIST_AND
+ );
+ }
- $res = $dbr->select(
- 'page',
- array( 'page_id', 'page_namespace', 'page_title', 'page_is_redirect', 'page_len', 'page_latest' ),
- $dbr->makeList( $where, LIST_OR ),
- __METHOD__
- );
+ $res = $dbr->select(
+ 'page',
+ array( 'page_id', 'page_namespace', 'page_title', 'page_is_redirect', 'page_len', 'page_latest' ),
+ $dbr->makeList( $where, LIST_OR ),
+ __METHOD__
+ );
- # Fetch data and form into an associative array
- # non-existent = broken
- foreach ( $res as $s ) {
- $title = Title::makeTitle( $s->page_namespace, $s->page_title );
- $pdbk = $title->getPrefixedDBkey();
- $linkCache->addGoodLinkObjFromRow( $title, $s );
- $output->addLink( $title, $s->page_id );
- # @todo FIXME: Convoluted data flow
- # The redirect status and length is passed to getLinkColour via the LinkCache
- # Use formal parameters instead
- $colours[$pdbk] = Linker::getLinkColour( $title, $threshold );
- //add id to the extension todolist
- $linkcolour_ids[$s->page_id] = $pdbk;
+ # Fetch data and form into an associative array
+ # non-existent = broken
+ foreach ( $res as $s ) {
+ $title = Title::makeTitle( $s->page_namespace, $s->page_title );
+ $pdbk = $title->getPrefixedDBkey();
+ $linkCache->addGoodLinkObjFromRow( $title, $s );
+ $output->addLink( $title, $s->page_id );
+ # @todo FIXME: Convoluted data flow
+ # The redirect status and length is passed to getLinkColour via the LinkCache
+ # Use formal parameters instead
+ $colours[$pdbk] = Linker::getLinkColour( $title, $threshold );
+ //add id to the extension todolist
+ $linkcolour_ids[$s->page_id] = $pdbk;
+ }
+ unset( $res );
}
- unset( $res );
- }
- if ( count( $linkcolour_ids ) ) {
- //pass an array of page_ids to an extension
- wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
+ if ( count( $linkcolour_ids ) ) {
+ //pass an array of page_ids to an extension
+ wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
+ }
+ wfProfileOut( __METHOD__ . '-check' );
}
- wfProfileOut( __METHOD__ . '-check' );
# Do a second query for different language variants of links and categories
- if( $wgContLang->hasVariants() ) {
+ if ( $wgContLang->hasVariants() ) {
$this->doVariants( $colours );
}
@@ -377,6 +379,10 @@ class LinkHolderArray {
$key = "$ns:$index";
$searchkey = "<!--LINK $key-->";
$displayText = $entry['text'];
+ if ( isset( $entry['selflink'] ) ) {
+ $replacePairs[$searchkey] = Linker::makeSelfLinkObj( $title, $displayText, $query );
+ continue;
+ }
if ( $displayText === '' ) {
$displayText = null;
}
@@ -406,7 +412,8 @@ class LinkHolderArray {
$text = preg_replace_callback(
'/(<!--LINK .*?-->)/',
$replacer->cb(),
- $text);
+ $text
+ );
wfProfileOut( __METHOD__ . '-replace' );
wfProfileOut( __METHOD__ );
@@ -424,7 +431,7 @@ class LinkHolderArray {
# Make interwiki link HTML
$output = $this->parent->getOutput();
$replacePairs = array();
- foreach( $this->interwikis as $key => $link ) {
+ foreach ( $this->interwikis as $key => $link ) {
$replacePairs[$key] = Linker::link( $link['title'], $link['text'] );
$output->addInterwikiLink( $link['title'] );
}
@@ -454,20 +461,17 @@ class LinkHolderArray {
// single string to all variants. This would improve parser's performance
// significantly.
foreach ( $this->internals as $ns => $entries ) {
+ if ( $ns == NS_SPECIAL ) {
+ continue;
+ }
foreach ( $entries as $index => $entry ) {
$pdbk = $entry['pdbk'];
// we only deal with new links (in its first query)
if ( !isset( $colours[$pdbk] ) || $colours[$pdbk] === 'new' ) {
- $title = $entry['title'];
- $titleText = $title->getText();
- $titlesAttrs[] = array(
- 'ns' => $ns,
- 'key' => "$ns:$index",
- 'titleText' => $titleText,
- );
+ $titlesAttrs[] = array( $index, $entry['title'] );
// separate titles with \0 because it would never appears
// in a valid title
- $titlesToBeConverted .= $titleText . "\0";
+ $titlesToBeConverted .= $entry['title']->getText() . "\0";
}
}
}
@@ -478,19 +482,35 @@ class LinkHolderArray {
foreach ( $titlesAllVariants as &$titlesVariant ) {
$titlesVariant = explode( "\0", $titlesVariant );
}
- $l = count( $titlesAttrs );
+
// Then add variants of links to link batch
- for ( $i = 0; $i < $l; $i ++ ) {
+ $parentTitle = $this->parent->getTitle();
+ foreach ( $titlesAttrs as $i => $attrs ) {
+ list( $index, $title ) = $attrs;
+ $ns = $title->getNamespace();
+ $text = $title->getText();
+
foreach ( $allVariantsName as $variantName ) {
$textVariant = $titlesAllVariants[$variantName][$i];
- if ( $textVariant != $titlesAttrs[$i]['titleText'] ) {
- $variantTitle = Title::makeTitle( $titlesAttrs[$i]['ns'], $textVariant );
- if( is_null( $variantTitle ) ) {
- continue;
- }
- $linkBatch->addObj( $variantTitle );
- $variantMap[$variantTitle->getPrefixedDBkey()][] = $titlesAttrs[$i]['key'];
+ if ( $textVariant === $text ) {
+ continue;
}
+
+ $variantTitle = Title::makeTitle( $ns, $textVariant );
+ if ( is_null( $variantTitle ) ) {
+ continue;
+ }
+
+ // Self-link checking for mixed/different variant titles. At this point, we
+ // already know the exact title does not exist, so the link cannot be to a
+ // variant of the current title that exists as a separate page.
+ if ( $variantTitle->equals( $parentTitle ) && $title->getFragment() === '' ) {
+ $this->internals[$ns][$index]['selflink'] = true;
+ continue 2;
+ }
+
+ $linkBatch->addObj( $variantTitle );
+ $variantMap[$variantTitle->getPrefixedDBkey()][] = "$ns:$index";
}
}
@@ -513,7 +533,7 @@ class LinkHolderArray {
}
}
- if( !$linkBatch->isEmpty() ) {
+ if ( !$linkBatch->isEmpty() ) {
// construct query
$dbr = wfGetDB( DB_SLAVE );
$varRes = $dbr->select( 'page',
@@ -532,14 +552,14 @@ class LinkHolderArray {
$vardbk = $variantTitle->getDBkey();
$holderKeys = array();
- if( isset( $variantMap[$varPdbk] ) ) {
+ if ( isset( $variantMap[$varPdbk] ) ) {
$holderKeys = $variantMap[$varPdbk];
$linkCache->addGoodLinkObjFromRow( $variantTitle, $s );
$output->addLink( $variantTitle, $s->page_id );
}
// loop over link holders
- foreach( $holderKeys as $key ) {
+ foreach ( $holderKeys as $key ) {
list( $ns, $index ) = explode( ':', $key, 2 );
$entry =& $this->internals[$ns][$index];
$pdbk = $entry['pdbk'];
@@ -569,12 +589,12 @@ class LinkHolderArray {
wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
// rebuild the categories in original order (if there are replacements)
- if( count( $varCategories ) > 0 ) {
+ if ( count( $varCategories ) > 0 ) {
$newCats = array();
$originalCats = $output->getCategories();
- foreach( $originalCats as $cat => $sortkey ) {
+ foreach ( $originalCats as $cat => $sortkey ) {
// make the replacement
- if( array_key_exists( $cat, $varCategories ) ) {
+ if ( array_key_exists( $cat, $varCategories ) ) {
$newCats[$varCategories[$cat]] = $sortkey;
} else {
$newCats[$cat] = $sortkey;
@@ -614,13 +634,13 @@ class LinkHolderArray {
function replaceTextCallback( $matches ) {
$type = $matches[1];
$key = $matches[2];
- if( $type == 'LINK' ) {
+ if ( $type == 'LINK' ) {
list( $ns, $index ) = explode( ':', $key, 2 );
- if( isset( $this->internals[$ns][$index]['text'] ) ) {
+ if ( isset( $this->internals[$ns][$index]['text'] ) ) {
return $this->internals[$ns][$index]['text'];
}
- } elseif( $type == 'IWLINK' ) {
- if( isset( $this->interwikis[$key]['text'] ) ) {
+ } elseif ( $type == 'IWLINK' ) {
+ if ( isset( $this->interwikis[$key]['text'] ) ) {
return $this->interwikis[$key]['text'];
}
}