Fixes and improvements to interwiki transclusion:
authorTim Starling <tstarling@users.mediawiki.org>
Tue, 31 Jan 2006 03:44:08 +0000 (03:44 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Tue, 31 Jan 2006 03:44:08 +0000 (03:44 +0000)
* allow interwiki {{subst:...}} using action=raw fetches
* Allowed non-MSIE browsers to access action=raw via the article alias. This is necessary to allow action=raw transclusion, since the only known URL is the article path, not the script path.
* Specify a user agent in wfGetHttp() fetches, when using curl.
* Added transcache table to tables.sql, it was in the updater but not there for some reason.
* Fixed transcache expiry, added option
* Allow interwiki transclusion outside the template namespace using leading colon syntax. Syntax is counterintuitive at times, e.g. to subst the wikipedia main page you would use {{subst::Wikipedia:Main_Page}} not {{subst:Wikipedia::Main_Page}}.

includes/DefaultSettings.php
includes/HttpFunctions.php
includes/Parser.php
includes/RawPage.php
maintenance/archives/patch-transcache.sql
maintenance/mysql5/tables.sql
maintenance/tables.sql

index 31ef629..f6ff4f2 100644 (file)
@@ -1831,6 +1831,10 @@ $wgHTTPProxy = false;
  * Enable interwiki transcluding.  Only when iw_trans=1.
  */
 $wgEnableScaryTranscluding = false;
+/**
+ * Expiry time for interwiki transclusion
+ */
+$wgTranscludeCacheExpiry = 3600;
 
 /**
  * Support blog-style "trackbacks" for articles.  See
index c7cc038..9dbfe01 100644 (file)
@@ -9,20 +9,22 @@
  * if $timeout is 'default', $wgHTTPTimeout is used
  */
 function wfGetHTTP( $url, $timeout = 'default' ) {
-       global $wgHTTPTimeout, $wgHTTPProxy;
+       global $wgHTTPTimeout, $wgHTTPProxy, $wgVersion;
 
        # Use curl if available
        if ( function_exists( 'curl_init' ) ) {
                $c = curl_init( $url );
                if ( wfIsLocalURL( $url ) ) {
                        curl_setopt( $c, CURLOPT_PROXY, 'localhost:80' );
-               } else if ($wgHTTPProxy)
+               } else if ($wgHTTPProxy) {
                        curl_setopt($c, CURLOPT_PROXY, $wgHTTPProxy);
+               }
 
                if ( $timeout == 'default' ) {
                        $timeout = $wgHTTPTimeout;
                }
                curl_setopt( $c, CURLOPT_TIMEOUT, $timeout );
+               curl_setopt( $c, CURLOPT_USERAGENT, "MediaWiki/$wgVersion" );
                ob_start();
                curl_exec( $c );
                $text = ob_get_contents();
index 580d63b..5d5c4b4 100644 (file)
@@ -2359,6 +2359,8 @@ class Parser
                $found = false;
                $nowiki = false;
                $noparse = false;
+               $replaceHeadings = false;
+               $isHTML = false;
 
                $title = NULL;
 
@@ -2531,8 +2533,6 @@ class Parser
                }
 
                # Load from database
-               $replaceHeadings = false;
-               $isHTML = false;
                $lastPathLevel = $this->mTemplatePath;
                if ( !$found ) {
                        $ns = NS_TEMPLATE;
@@ -2542,46 +2542,51 @@ class Parser
                        }
                        $title = Title::newFromText( $part1, $ns );
 
-                       if ($title) {
-                               $interwiki = Title::getInterwikiLink($title->getInterwiki());
-                               if ($interwiki != '' && $title->isTrans()) {
-                                       return $this->scarytransclude($title, $interwiki);
-                               }
-                       }
-
-                       if ( !is_null( $title ) && !$title->isExternal() ) {
-                               # Check for excessive inclusion
-                               $dbk = $title->getPrefixedDBkey();
-                               if ( $this->incrementIncludeCount( $dbk ) ) {
-                                       if ( $title->getNamespace() == NS_SPECIAL && $this->mOptions->getAllowSpecialInclusion() ) {
-                                               # Capture special page output
-                                               $text = SpecialPage::capturePath( $title );
-                                               if ( is_string( $text ) ) {
-                                                       $found = true;
-                                                       $noparse = true;
-                                                       $isHTML = true;
-                                                       $this->disableCache();
-                                               }
-                                       } else {
-                                               $articleContent = $this->fetchTemplate( $title );
-                                               if ( $articleContent !== false ) {
-                                                       $found = true;
-                                                       $text = $articleContent;
-                                                       $replaceHeadings = true;
+                       if ( !is_null( $title ) ) {
+                               if ( !$title->isExternal() ) {
+                                       # Check for excessive inclusion
+                                       $dbk = $title->getPrefixedDBkey();
+                                       if ( $this->incrementIncludeCount( $dbk ) ) {
+                                               if ( $title->getNamespace() == NS_SPECIAL && $this->mOptions->getAllowSpecialInclusion() ) {
+                                                       # Capture special page output
+                                                       $text = SpecialPage::capturePath( $title );
+                                                       if ( is_string( $text ) ) {
+                                                               $found = true;
+                                                               $noparse = true;
+                                                               $isHTML = true;
+                                                               $this->disableCache();
+                                                       }
+                                               } else {
+                                                       $articleContent = $this->fetchTemplate( $title );
+                                                       if ( $articleContent !== false ) {
+                                                               $found = true;
+                                                               $text = $articleContent;
+                                                               $replaceHeadings = true;
+                                                       }
                                                }
                                        }
-                               }
 
-                               # If the title is valid but undisplayable, make a link to it
-                               if ( $this->mOutputType == OT_HTML && !$found ) {
-                                       $text = '[['.$title->getPrefixedText().']]';
-                                       $found = true;
-                               }
+                                       # If the title is valid but undisplayable, make a link to it
+                                       if ( $this->mOutputType == OT_HTML && !$found ) {
+                                               $text = '[['.$title->getPrefixedText().']]';
+                                               $found = true;
+                                       }
 
-                               # Template cache array insertion
-                               if( $found ) {
-                                       $this->mTemplates[$part1] = $text;
-                                       $text = $linestart . $text;
+                                       # Template cache array insertion
+                                       if( $found ) {
+                                               $this->mTemplates[$part1] = $text;
+                                               $text = $linestart . $text;
+                                       }
+                               } elseif ( $title->isTrans() ) {
+                                       // Interwiki transclusion
+                                       if ( $this->mOutputType == OT_HTML ) {
+                                               $text = $this->interwikiTransclude( $title, 'render' );
+                                               $isHTML = true;
+                                               $noparse = true;
+                                       } else {
+                                               $text = $this->interwikiTransclude( $title, 'raw' );
+                                       }
+                                       $found = true;
                                }
                        }
                }
@@ -2714,41 +2719,49 @@ class Parser
        }
 
        /**
-        * Translude an interwiki link.
+        * Transclude an interwiki link.
         */
-       function scarytransclude($title, $interwiki) {
-               global $wgEnableScaryTranscluding;
+       function interwikiTransclude( $title, $action ) {
+               global $wgEnableScaryTranscluding, $wgCanonicalNamespaceNames;
 
                if (!$wgEnableScaryTranscluding)
                        return wfMsg('scarytranscludedisabled');
 
-               $articlename = "Template:" . $title->getDBkey();
-               $url = str_replace('$1', urlencode($articlename), $interwiki);
+               // The namespace will actually only be 0 or 10, depending on whether there was a leading :
+               // But we'll handle it generally anyway
+               if ( $title->getNamespace() ) {
+                       // Use the canonical namespace, which should work anywhere
+                       $articleName = $wgCanonicalNamespaceNames[$title->getNamespace()] . ':' . $title->getDBkey();
+               } else {
+                       $articleName = $title->getDBkey();
+               }
+
+               $url = str_replace('$1', urlencode($articleName), Title::getInterwikiLink($title->getInterwiki()));
+               $url .= "?action=$action";
                if (strlen($url) > 255)
                        return wfMsg('scarytranscludetoolong');
-               $text = $this->fetchScaryTemplateMaybeFromCache($url);
-               $this->mIWTransData[] = $text;
-               return "<!--IW_TRANSCLUDE ".(count($this->mIWTransData) - 1)."-->";
+               return $this->fetchScaryTemplateMaybeFromCache($url);
        }
 
        function fetchScaryTemplateMaybeFromCache($url) {
+               global $wgTranscludeCacheExpiry;
                $dbr =& wfGetDB(DB_SLAVE);
                $obj = $dbr->selectRow('transcache', array('tc_time', 'tc_contents'),
                                array('tc_url' => $url));
                if ($obj) {
                        $time = $obj->tc_time;
                        $text = $obj->tc_contents;
-                       if ($time && $time < (time() + (60*60))) {
+                       if ($time && time() < $time + $wgTranscludeCacheExpiry ) {
                                return $text;
                        }
                }
 
-               $text = wfGetHTTP($url . '?action=render');
+               $text = wfGetHTTP($url);
                if (!$text)
                        return wfMsg('scarytranscludefailed', $url);
 
                $dbw =& wfGetDB(DB_MASTER);
-               $dbw->replace('transcache', array(), array(
+               $dbw->replace('transcache', array('tc_url'), array(
                        'tc_url' => $url,
                        'tc_time' => time(),
                        'tc_contents' => $text));
index b5bc548..1093cf9 100644 (file)
@@ -83,7 +83,9 @@ class RawPage {
                } else {
                        $url = $_SERVER['PHP_SELF'];
                }
-               if( strcmp( $wgScript, $url ) ) {
+               
+               $ua = @$_SERVER['HTTP_USER_AGENT'];
+               if( strcmp( $wgScript, $url ) && strpos( $ua, 'MSIE' ) !== false ) {
                        # Internet Explorer will ignore the Content-Type header if it
                        # thinks it sees a file extension it recognizes. Make sure that
                        # all raw requests are done through the script node, which will
index 2bdc10c..a244bff 100644 (file)
@@ -3,5 +3,5 @@ CREATE TABLE /*$wgDBprefix*/transcache (
        tc_contents     TEXT,
        tc_time         INT NOT NULL,
        UNIQUE INDEX tc_url_idx(tc_url)
-);
+) TYPE=InnoDB;
 
index f08e39f..1186250 100644 (file)
@@ -851,6 +851,16 @@ CREATE TABLE /*$wgDBprefix*/objectcache (
 
 ) TYPE=InnoDB, DEFAULT CHARSET=utf8;
 
+--
+-- Cache of interwiki transclusion
+--
+CREATE TABLE /*$wgDBprefix*/transcache (
+       tc_url          VARCHAR(255) NOT NULL,
+       tc_contents     TEXT,
+       tc_time         INT NOT NULL,
+       UNIQUE INDEX tc_url_idx(tc_url)
+) TYPE=InnoDB, DEFAULT CHARSET=utf8;
+
 -- For article validation
 CREATE TABLE /*$wgDBprefix*/validate (
   val_user int(11) NOT NULL default '0',
index 2aa58c4..e902cd6 100644 (file)
@@ -838,6 +838,16 @@ CREATE TABLE /*$wgDBprefix*/objectcache (
 
 ) TYPE=InnoDB;
 
+--
+-- Cache of interwiki transclusion
+--
+CREATE TABLE /*$wgDBprefix*/transcache (
+       tc_url          VARCHAR(255) NOT NULL,
+       tc_contents     TEXT,
+       tc_time         INT NOT NULL,
+       UNIQUE INDEX tc_url_idx(tc_url)
+) TYPE=InnoDB;
+
 -- For article validation
 CREATE TABLE /*$wgDBprefix*/validate (
   val_user int(11) NOT NULL default '0',