if($wgUseTeX) require_once( "Math.php" );
+define( 'RLH_FOR_UPDATE', 1 );
+
class OutputPage {
var $mHeaders, $mCookies, $mMetatags, $mKeywords;
var $mLinktags, $mPagetitle, $mBodytext, $mDebugtext;
var $mHTMLtitle, $mRobotpolicy, $mIsarticle, $mPrintable;
var $mSubtitle, $mRedirect;
var $mLastModified, $mCategoryLinks;
- var $mScripts;
+ var $mScripts, $mLinkColours;
var $mSuppressQuickbar;
var $mOnloadHandler;
$this->sendCacheControl();
# Perform link colouring
- $this->mBodytext = $this->parseLinkHolders();
+ $this->replaceLinkHolders();
# Disable temporary placeholders, so that the skin produces HTML
$sk->postParseLinkColour( false );
print "$msg\n";
wfErrorExit();
}
- $sk = $wgUser->getSkin();
- $shlink = $sk->makeKnownLink( wfMsgNoDB( "searchhelppage" ),
- wfMsgNoDB( "searchingwikipedia" ) );
- $msg = str_replace( "$5", $shlink, $msg );
$this->mBodytext = $msg;
$this->output();
wfErrorExit();
$a = array_slice ( $a , 0 , 10 ) ; # 10 keywords max
$a = implode ( "," , $a ) ;
$strip = array(
- "/<.*?>/" => '',
+ "/<.*?" . ">/" => '',
"/[_]/" => ' '
);
$a = htmlspecialchars(preg_replace(array_keys($strip), array_values($strip),$a ));
if ( count( $this->mKeywords ) > 0 ) {
$strip = array(
- "/<.*?>/" => '',
+ "/<.*?" . ">/" => '',
"/[_]/" => ' '
);
$ret .= "<meta name=\"keywords\" content=\"" .
return $ret;
}
- # Parse <!--LINK--> link placeholders to avoid using linkcache
+ # Replace <!--LINK--> link placeholders with actual links, in the buffer
# Placeholders created in Skin::makeLinkObj()
- function parseLinkHolders()
+ # Returns an array of links found, indexed by PDBK:
+ # 0 - broken
+ # 1 - normal link
+ # 2 - stub
+ # $options is a bit field, RLH_FOR_UPDATE to select for update
+ function replaceLinkHolders( $options = 0 )
{
- global $wgUser;
+ global $wgUser, $wgLinkCache, $wgUseOldExistenceCheck;
- $fname = 'OutputPage::parseLinkHolders';
+ if ( $wgUseOldExistenceCheck ) {
+ return array();
+ }
+
+ $fname = 'OutputPage::replaceLinkHolders';
wfProfileIn( $fname );
+
+ $titles = array();
+ $pdbks = array();
+ $colours = array();
# Get placeholders from body
+ wfProfileIn( "$fname-match" );
preg_match_all( "/<!--LINK (.*?) (.*?) (.*?) (.*?)-->/", $this->mBodytext, $tmpLinks );
+ wfProfileOut( "$fname-match" );
if ( !empty( $tmpLinks[0] ) ) {
+ wfProfileIn( "$fname-check" );
$dbr =& wfGetDB( DB_SLAVE );
$cur = $dbr->tableName( 'cur' );
$sk = $wgUser->getSkin();
asort( $namespaces );
# Generate query
+ $query = false;
foreach ( $namespaces as $key => $val ) {
- if ( !isset( $current ) ) {
- $current = $val;
- $query = "SELECT cur_namespace, cur_title";
- if ( $threshold > 0 ) {
- $query .= ", LENGTH(cur_text) AS cur_len, cur_is_redirect";
- }
- $query .= " FROM $cur WHERE (cur_namespace=$val AND cur_title IN(";
- } elseif ( $current != $val ) {
- $current = $val;
- $query .= ")) OR (cur_namespace=$val AND cur_title IN(";
- } else {
- $query .= ", ";
+ # Make title object
+ $dbk = $dbkeys[$key];
+ $title = $titles[$key] = Title::makeTitle( $val, $dbk );
+
+ # Skip invalid entries.
+ # Result will be ugly, but prevents crash.
+ if ( is_null( $title ) ) {
+ continue;
}
+ $pdbk = $pdbks[$key] = $title->getPrefixedDBkey();
+
+ # Check if it's in the link cache already
+ if ( $wgLinkCache->getGoodLinkID( $pdbk ) ) {
+ $colours[$pdbk] = 1;
+ } elseif ( $wgLinkCache->isBadLink( $pdbk ) ) {
+ $colours[$pdbk] = 0;
+ } else {
+ # Not in the link cache, add it to the query
+ if ( !isset( $current ) ) {
+ $current = $val;
+ $query = "SELECT cur_id, cur_namespace, cur_title";
+ if ( $threshold > 0 ) {
+ $query .= ", LENGTH(cur_text) AS cur_len, cur_is_redirect";
+ }
+ $query .= " FROM $cur WHERE (cur_namespace=$val AND cur_title IN(";
+ } elseif ( $current != $val ) {
+ $current = $val;
+ $query .= ")) OR (cur_namespace=$val AND cur_title IN(";
+ } else {
+ $query .= ", ";
+ }
- $query .= $dbr->addQuotes( $dbkeys[$key] );
+ $query .= $dbr->addQuotes( $dbkeys[$key] );
+ }
}
-
- $query .= "))";
-
- $res = $dbr->query( $query, $fname );
+ if ( $query ) {
+ $query .= "))";
+ if ( $options & RLH_FOR_UPDATE ) {
+ $query .= " FOR UPDATE";
+ }
- # Fetch data and form into an associative array
- # non-existent = broken
- # 1 = known
- # 2 = stub
- $colours = array();
- while ( $s = $dbr->fetchObject($res) ) {
- $key = $s->cur_namespace . ' ' . $s->cur_title;
- if ( $threshold > 0 ) {
- $size = $s->cur_len;
- if ( $s->cur_is_redirect || $s->cur_namespace != 0 || $length < $threshold ) {
- $colours[$key] = 1;
+ $res = $dbr->query( $query, $fname );
+
+ # Fetch data and form into an associative array
+ # non-existent = broken
+ # 1 = known
+ # 2 = stub
+ while ( $s = $dbr->fetchObject($res) ) {
+ $title = Title::makeTitle( $s->cur_namespace, $s->cur_title );
+ $pdbk = $title->getPrefixedDBkey();
+ $wgLinkCache->addGoodLink( $s->cur_id, $pdbk );
+
+ if ( $threshold > 0 ) {
+ $size = $s->cur_len;
+ if ( $s->cur_is_redirect || $s->cur_namespace != 0 || $length < $threshold ) {
+ $colours[$pdbk] = 1;
+ } else {
+ $colours[$pdbk] = 2;
+ }
} else {
- $colours[$key] = 2;
+ $colours[$pdbk] = 1;
}
- $colours[$key] = array( $s->cur_len, $s->cur_is_redirect );
- } else {
- $colours[$key] = 1;
}
}
+ wfProfileOut( "$fname-check" );
# Construct search and replace arrays
+ wfProfileIn( "$fname-construct" );
$search = $replace = array();
foreach ( $namespaces as $key => $ns ) {
- $cKey = $ns . ' ' . $dbkeys[$key];
+ $pdbk = $pdbks[$key];
$search[] = $tmpLinks[0][$key];
- $title = Title::makeTitle( $ns, $dbkeys[$key] );
- if ( empty( $colours[$cKey] ) ) {
+ $title = $titles[$key];
+ if ( empty( $colours[$pdbk] ) ) {
+ $wgLinkCache->addBadLink( $pdbk );
+ $colours[$pdbk] = 0;
$replace[] = $sk->makeBrokenLinkObj( $title, $texts[$key], $queries[$key] );
- } elseif ( $colours[$cKey] == 1 ) {
+ } elseif ( $colours[$pdbk] == 1 ) {
$replace[] = $sk->makeKnownLinkObj( $title, $texts[$key], $queries[$key] );
- } elseif ( $colours[$cKey] == 2 ) {
+ } elseif ( $colours[$pdbk] == 2 ) {
$replace[] = $sk->makeStubLinkObj( $title, $texts[$key], $queries[$key] );
}
}
-
+ wfProfileOut( "$fname-construct" );
# Do the thing
- $out = str_replace( $search, $replace, $this->mBodytext );
- } else {
- $out = $this->mBodytext;
+ wfProfileIn( "$fname-replace" );
+ $this->mBodytext = str_replace( $search, $replace, $this->mBodytext );
+ wfProfileOut( "$fname-replace" );
}
-
wfProfileOut( $fname );
- return ( $out );
+ return $colours;
}
}