Various improvements to interwiki transclusion. Introduced {{raw:..}}, to force raw...
authorTim Starling <tstarling@users.mediawiki.org>
Wed, 1 Feb 2006 04:41:53 +0000 (04:41 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Wed, 1 Feb 2006 04:41:53 +0000 (04:41 +0000)
RELEASE-NOTES
includes/HttpFunctions.php
includes/MagicWord.php
includes/Parser.php
includes/Title.php
languages/Language.php

index 695b744..c7cf0fe 100644 (file)
@@ -258,6 +258,7 @@ Parser:
   character before doing anything with them. This prevents certain kinds of
   spam filter evasion.
 * (bug 4783) : Fix for "{{ns:0}} does not render"
+* Improved support for interwiki transclusion
 
 Upload:
 * (bug 2527) Always set destination filename when new file is selected
index 9dbfe01..2c2fd4c 100644 (file)
@@ -9,7 +9,7 @@
  * if $timeout is 'default', $wgHTTPTimeout is used
  */
 function wfGetHTTP( $url, $timeout = 'default' ) {
-       global $wgHTTPTimeout, $wgHTTPProxy, $wgVersion;
+       global $wgHTTPTimeout, $wgHTTPProxy, $wgVersion, $wgTitle, $wgCommandLineMode;
 
        # Use curl if available
        if ( function_exists( 'curl_init' ) ) {
@@ -25,6 +25,16 @@ function wfGetHTTP( $url, $timeout = 'default' ) {
                }
                curl_setopt( $c, CURLOPT_TIMEOUT, $timeout );
                curl_setopt( $c, CURLOPT_USERAGENT, "MediaWiki/$wgVersion" );
+
+               # Set the referer to $wgTitle, even in command-line mode
+               # This is useful for interwiki transclusion, where the foreign
+               # server wants to know what the referring page is.
+               # $_SERVER['REQUEST_URI'] gives a less reliable indication of the 
+               # referring page.
+               if ( is_object( $wgTitle ) ) {
+                       curl_setopt( $c, CURLOPT_REFERER, $wgTitle->getFullURL() );
+               }
+
                ob_start();
                curl_exec( $c );
                $text = ob_get_contents();
index 2c09165..9d0b3bf 100644 (file)
@@ -69,6 +69,7 @@ $magicWords = array(
        'MAG_UC',
        'MAG_FULLPAGENAME',
        'MAG_FULLPAGENAMEE',
+       'MAG_RAW',
 );
 if ( ! defined( 'MEDIAWIKI_INSTALL' ) )
        wfRunHooks( 'MagicWordMagicWords', array( &$magicWords ) );
index 5d5c4b4..13b5f2e 100644 (file)
@@ -2253,9 +2253,10 @@ class Parser
         *
         * @param string $tex The text to transform
         * @param array $args Key-value pairs representing template parameters to substitute
+        * @param bool $argsOnly Only do argument (triple-brace) expansion, not double-brace expansion
         * @access private
         */
-       function replaceVariables( $text, $args = array() ) {
+       function replaceVariables( $text, $args = array(), $argsOnly = false ) {
                # Prevent too big inclusions
                if( strlen( $text ) > MAX_INCLUDE_SIZE ) {
                        return $text;
@@ -2268,7 +2269,9 @@ class Parser
                array_push( $this->mArgStack, $args );
 
                $braceCallbacks = array();
-               $braceCallbacks[2] = array( &$this, 'braceSubstitution' );
+               if ( !$argsOnly ) {
+                       $braceCallbacks[2] = array( &$this, 'braceSubstitution' );
+               }
                if ( $this->mOutputType == OT_HTML || $this->mOutputType == OT_WIKI ) {
                        $braceCallbacks[3] = array( &$this, 'argSubstitution' );
                }
@@ -2356,12 +2359,16 @@ class Parser
                $fname = 'Parser::braceSubstitution';
                wfProfileIn( $fname );
 
-               $found = false;
-               $nowiki = false;
-               $noparse = false;
-               $replaceHeadings = false;
-               $isHTML = false;
+               # Flags 
+               $found = false;             # $text has been filled
+               $nowiki = false;            # wiki markup in $text should be escaped
+               $noparse = false;           # Unsafe HTML tags should not be stripped, etc.
+               $noargs = false;            # Don't replace triple-brace arguments in $text
+               $replaceHeadings = false;   # Make the edit section links go to the template not the article
+               $isHTML = false;            # $text is HTML, armour it against wikitext transformation
+               $forceRawInterwiki = false; # Force interwiki transclusion to be done in raw mode not rendered
 
+               # Title object, where $text came from
                $title = NULL;
 
                $linestart = '';
@@ -2378,6 +2385,7 @@ class Parser
                                $text = $replaceWith;
                                $found = true;
                                $noparse = true;
+                               $noargs = true;
                        }
                }
 
@@ -2395,10 +2403,11 @@ class Parser
                                $text = $piece['text'];
                                $found = true;
                                $noparse = true;
+                               $noargs = true;
                        }
                }
 
-               # MSG, MSGNW and INT
+               # MSG, MSGNW, INT and RAW
                if ( !$found ) {
                        # Check for MSGNW:
                        $mwMsgnw =& MagicWord::get( MAG_MSGNW );
@@ -2409,7 +2418,13 @@ class Parser
                                $mwMsg =& MagicWord::get( MAG_MSG );
                                $mwMsg->matchStartAndRemove( $part1 );
                        }
-
+                       
+                       # Check for RAW:
+                       $mwRaw =& MagicWord::get( MAG_RAW );
+                       if ( $mwRaw->matchStartAndRemove( $part1 ) ) {
+                               $forceRawInterwiki = true;
+                       }
+                       
                        # Check if it is an internal message
                        $mwInt =& MagicWord::get( MAG_INT );
                        if ( $mwInt->matchStartAndRemove( $part1 ) ) {
@@ -2515,12 +2530,13 @@ class Parser
 
                # Did we encounter this template already? If yes, it is in the cache
                # and we need to check for loops.
-               if ( !$found && isset( $this->mTemplates[$part1] ) ) {
+               if ( !$found && isset( $this->mTemplates[$piece['title']] ) ) {
                        $found = true;
 
                        # Infinite loop test
                        if ( isset( $this->mTemplatePath[$part1] ) ) {
                                $noparse = true;
+                               $noargs = true;
                                $found = true;
                                $text = $linestart .
                                        '{{' . $part1 . '}}' .
@@ -2528,7 +2544,7 @@ class Parser
                                wfDebug( "$fname: template loop broken at '$part1'\n" );
                        } else {
                                # set $text to cached message.
-                               $text = $linestart . $this->mTemplates[$part1];
+                               $text = $linestart . $this->mTemplates[$piece['title']];
                        }
                }
 
@@ -2553,6 +2569,7 @@ class Parser
                                                        if ( is_string( $text ) ) {
                                                                $found = true;
                                                                $noparse = true;
+                                                               $noargs = true;
                                                                $isHTML = true;
                                                                $this->disableCache();
                                                        }
@@ -2571,23 +2588,26 @@ class Parser
                                                $text = '[['.$title->getPrefixedText().']]';
                                                $found = true;
                                        }
-
-                                       # Template cache array insertion
-                                       if( $found ) {
-                                               $this->mTemplates[$part1] = $text;
-                                               $text = $linestart . $text;
-                                       }
                                } elseif ( $title->isTrans() ) {
                                        // Interwiki transclusion
-                                       if ( $this->mOutputType == OT_HTML ) {
+                                       if ( $this->mOutputType == OT_HTML && !$forceRawInterwiki ) {
                                                $text = $this->interwikiTransclude( $title, 'render' );
                                                $isHTML = true;
                                                $noparse = true;
                                        } else {
                                                $text = $this->interwikiTransclude( $title, 'raw' );
+                                               $replaceHeadings = true;
                                        }
                                        $found = true;
                                }
+                               
+                               # Template cache array insertion
+                               # Use the original $piece['title'] not the mangled $part1, so that
+                               # modifiers such as RAW: produce separate cache entries
+                               if( $found ) {
+                                       $this->mTemplates[$piece['title']] = $text;
+                                       $text = $linestart . $text;
+                               }
                        }
                }
 
@@ -2595,51 +2615,60 @@ class Parser
                # Only for HTML output
                if ( $nowiki && $found && $this->mOutputType == OT_HTML ) {
                        $text = wfEscapeWikiText( $text );
-               } elseif ( ($this->mOutputType == OT_HTML || $this->mOutputType == OT_WIKI) && $found && !$noparse) {
-                       # Clean up argument array
-                       $assocArgs = array();
-                       $index = 1;
-                       foreach( $args as $arg ) {
-                               $eqpos = strpos( $arg, '=' );
-                               if ( $eqpos === false ) {
-                                       $assocArgs[$index++] = $arg;
-                               } else {
-                                       $name = trim( substr( $arg, 0, $eqpos ) );
-                                       $value = trim( substr( $arg, $eqpos+1 ) );
-                                       if ( $value === false ) {
-                                               $value = '';
-                                       }
-                                       if ( $name !== false ) {
-                                               $assocArgs[$name] = $value;
+               } elseif ( ($this->mOutputType == OT_HTML || $this->mOutputType == OT_WIKI) && $found ) {
+                       if ( !$noargs ) {
+                               # Clean up argument array
+                               $assocArgs = array();
+                               $index = 1;
+                               foreach( $args as $arg ) {
+                                       $eqpos = strpos( $arg, '=' );
+                                       if ( $eqpos === false ) {
+                                               $assocArgs[$index++] = $arg;
+                                       } else {
+                                               $name = trim( substr( $arg, 0, $eqpos ) );
+                                               $value = trim( substr( $arg, $eqpos+1 ) );
+                                               if ( $value === false ) {
+                                                       $value = '';
+                                               }
+                                               if ( $name !== false ) {
+                                                       $assocArgs[$name] = $value;
+                                               }
                                        }
                                }
-                       }
 
-                       # Add a new element to the templace recursion path
-                       $this->mTemplatePath[$part1] = 1;
-
-                       # If there are any <onlyinclude> tags, only include them
-                       if ( in_string( '<onlyinclude>', $text ) && in_string( '</onlyinclude>', $text ) ) {
-                               preg_match_all( '/<onlyinclude>(.*?)\n?<\/onlyinclude>/s', $text, $m );
-                               $text = '';
-                               foreach ($m[1] as $piece)
-                                       $text .= $piece;
+                               # Add a new element to the templace recursion path
+                               $this->mTemplatePath[$part1] = 1;
                        }
-                       # Remove <noinclude> sections and <includeonly> tags
-                       $text = preg_replace( '/<noinclude>.*?<\/noinclude>/s', '', $text );
-                       $text = strtr( $text, array( '<includeonly>' => '' , '</includeonly>' => '' ) );
 
-                       if( $this->mOutputType == OT_HTML ) {
-                               # Strip <nowiki>, <pre>, etc.
-                               $text = $this->strip( $text, $this->mStripState );
-                               $text = Sanitizer::removeHTMLtags( $text, array( &$this, 'replaceVariables' ), $assocArgs );
-                       }
-                       $text = $this->replaceVariables( $text, $assocArgs );
+                       if ( !$noparse ) {
+                               # If there are any <onlyinclude> tags, only include them
+                               if ( in_string( '<onlyinclude>', $text ) && in_string( '</onlyinclude>', $text ) ) {
+                                       preg_match_all( '/<onlyinclude>(.*?)\n?<\/onlyinclude>/s', $text, $m );
+                                       $text = '';
+                                       foreach ($m[1] as $piece)
+                                               $text .= $piece;
+                               }
+                               # Remove <noinclude> sections and <includeonly> tags
+                               $text = preg_replace( '/<noinclude>.*?<\/noinclude>/s', '', $text );
+                               $text = strtr( $text, array( '<includeonly>' => '' , '</includeonly>' => '' ) );
+
+                               if( $this->mOutputType == OT_HTML ) {
+                                       # Strip <nowiki>, <pre>, etc.
+                                       $text = $this->strip( $text, $this->mStripState );
+                                       $text = Sanitizer::removeHTMLtags( $text, array( &$this, 'replaceVariables' ), $assocArgs );
+                               }
+                               $text = $this->replaceVariables( $text, $assocArgs );
 
-                       # If the template begins with a table or block-level
-                       # element, it should be treated as beginning a new line.
-                       if (!$piece['lineStart'] && preg_match('/^({\\||:|;|#|\*)/', $text)) {
-                               $text = "\n" . $text;
+                               # If the template begins with a table or block-level
+                               # element, it should be treated as beginning a new line.
+                               if (!$piece['lineStart'] && preg_match('/^({\\||:|;|#|\*)/', $text)) {
+                                       $text = "\n" . $text;
+                               }
+                       } elseif ( !$noargs ) {
+                               # $noparse and !$noargs
+                               # Just replace the arguments, not any double-brace items
+                               # This is used for rendered interwiki transclusion
+                               $text = $this->replaceVariables( $text, $assocArgs, true );
                        }
                }
                # Prune lower levels off the recursion check path
index 40c0f52..4cbaa14 100644 (file)
@@ -494,7 +494,7 @@ class Title {
        function isTrans() {
                global $wgTitleInterwikiCache, $wgDBname;
 
-               if ($this->mInterwiki == '' || !$this->isLocal())
+               if ($this->mInterwiki == '')
                        return false;
                # Make sure key is loaded into cache
                $this->getInterwikiLink( $this->mInterwiki );
@@ -752,6 +752,13 @@ class Title {
 
                if ( $this->isExternal() ) {
                        $url = $this->getFullURL();
+                       if ( $query ) {
+                               // This is currently only used for edit section links in the 
+                               // context of interwiki transclusion. In theory we should 
+                               // append the query to the end of any existing query string,
+                               // but interwiki transclusion is already broken in that case.
+                               $url .= "?$query";
+                       }
                } else {
                        $dbkey = wfUrlencode( $this->getPrefixedDBkey() );
                        if ( $query == '' ) {
@@ -1344,6 +1351,13 @@ class Title {
                                                # Do another namespace split...
                                                continue;
                                        }
+
+                                       # If there's an initial colon after the interwiki, that also 
+                                       # resets the default namespace
+                                       if ( $t !== '' && $t[0] == ':' ) {
+                                               $this->mNamespace = NS_MAIN;
+                                               $t = substr( $t, 1 );
+                                       }
                                }
                                # If there's no recognized interwiki or namespace,
                                # then let the colon expression be part of the title.
index 33e96b4..1df20e6 100644 (file)
@@ -253,10 +253,11 @@ $wgLanguageNamesEn =& $wgLanguageNames;
        MAG_PLURAL               => array( 0,    'PLURAL:'                ),
        MAG_FULLURL              => array( 0,    'FULLURL:'               ),
        MAG_FULLURLE             => array( 0,    'FULLURLE:'              ),
-       MAG_LCFIRST              => array( 0,    'LCFIRST:'               ),
-       MAG_UCFIRST              => array( 0,    'UCFIRST:'               ),
-       MAG_LC                   => array( 0,    'LC:'                    ),
-       MAG_UC                   => array( 0,    'UC:'                    ),
+       MAG_LCFIRST              => array( 0,    'LCFIRST:'               ),
+       MAG_UCFIRST              => array( 0,    'UCFIRST:'               ),
+       MAG_LC                   => array( 0,    'LC:'                    ),
+       MAG_UC                   => array( 0,    'UC:'                    ),
+       MAG_RAW                  => array( 0,    'RAW:'                   ),
 );
 
 if (!$wgCachedMessageArrays) {