Fix for regression in variant short-URLs...
authorBrion Vibber <brion@users.mediawiki.org>
Thu, 17 May 2007 20:02:59 +0000 (20:02 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Thu, 17 May 2007 20:02:59 +0000 (20:02 +0000)
Cleaned up the new URL parsing code a bit, now able to recognize both $wgActionPaths and $wgVariantArticlePath and interpolate those variables.
Moved that bit into WebRequest::interpolateTitle() function which is called after $wgContLang stub object is created, so it can be used to get the variant list.
I'm not totally happy with all this code, but it works. The variant bits generally creep me out.

includes/Setup.php
includes/WebRequest.php

index 47ba494..7f964a1 100644 (file)
@@ -167,6 +167,10 @@ if ( !$wgDBservers ) {
 $wgLoadBalancer = new StubObject( 'wgLoadBalancer', 'LoadBalancer', 
        array( $wgDBservers, false, $wgMasterWaitTimeout, true ) );
 $wgContLang = new StubContLang;
+
+// Now that variant lists may be available...
+$wgRequest->interpolateTitle();
+
 $wgUser = new StubUser;
 $wgLang = new StubUserLang;
 $wgOut = new StubObject( 'wgOut', 'OutputPage' );
index 1a59766..5ba1203 100644 (file)
@@ -44,44 +44,93 @@ if ( !function_exists( '__autoload' ) ) {
 class WebRequest {
        function __construct() {
                $this->checkMagicQuotes();
+       }
+       
+       /**
+        * Check for title, action, and/or variant data in the URL
+        * and interpolate it into the GET variables.
+        * This should only be run after $wgContLang is available,
+        * as we may need the list of language variants to determine
+        * available variant URLs.
+        */
+       function interpolateTitle() {
                global $wgUsePathInfo;
                if ( $wgUsePathInfo ) {
                        // PATH_INFO is mangled due to http://bugs.php.net/bug.php?id=31892
                        // And also by Apache 2.x, double slashes are converted to single slashes.
                        // So we will use REQUEST_URI if possible.
-                       $title = '';
+                       $matches = array();
                        if ( !empty( $_SERVER['REQUEST_URI'] ) ) {
-                               global $wgArticlePath, $wgActionPaths;
-                               $paths["view"] = $wgArticlePath;
-                               $paths = array_merge( $paths, $wgActionPaths );
-                               $title = $this->extractActionPaths( $paths );
+                               // Slurp out the path portion to examine...
+                               $url = $_SERVER['REQUEST_URI'];
+                               if ( !preg_match( '!^https?://!', $url ) ) {
+                                       $url = 'http://unused' . $url;
+                               }
+                               $a = parse_url( $url );
+                               if( $a ) {
+                                       $path = $a['path'];
+                                       
+                                       global $wgArticlePath;
+                                       $matches = $this->extractTitle( $path, $wgArticlePath );
+                                       
+                                       global $wgActionPaths;
+                                       if( !$matches && $wgActionPaths) {
+                                               $matches = $this->extractTitle( $path, $wgActionPaths, 'action' );
+                                       }
+                                       
+                                       global $wgVariantArticlePath, $wgContLang;
+                                       if( !$matches && $wgVariantArticlePath ) {
+                                               $variantPaths = array();
+                                               foreach( $wgContLang->getVariants() as $variant ) {
+                                                       $variantPaths[$variant] =
+                                                               str_replace( '$2', $variant, $wgVariantArticlePath );
+                                               }
+                                               $matches = $this->extractTitle( $path, $variantPaths, 'variant' );
+                                       }
+                               }
                        } elseif ( isset( $_SERVER['ORIG_PATH_INFO'] ) && $_SERVER['ORIG_PATH_INFO'] != '' ) {
-                               # Mangled PATH_INFO
-                               # http://bugs.php.net/bug.php?id=31892
-                               # Also reported when ini_get('cgi.fix_pathinfo')==false
-                               $title = substr( $_SERVER['ORIG_PATH_INFO'], 1 );
-                       } elseif ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != '') && $wgUsePathInfo ) {
-                               $title = substr( $_SERVER['PATH_INFO'], 1 );
+                               // Mangled PATH_INFO
+                               // http://bugs.php.net/bug.php?id=31892
+                               // Also reported when ini_get('cgi.fix_pathinfo')==false
+                               $matches['title'] = substr( $_SERVER['ORIG_PATH_INFO'], 1 );
+                               
+                       } elseif ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != '') ) {
+                               // Regular old PATH_INFO yay
+                               $matches['title'] = substr( $_SERVER['PATH_INFO'], 1 );
                        }
-                       if ( strval( $title ) != '' ) {
-                               $_GET['title'] = $_REQUEST['title'] = $title;
+                       foreach( $matches as $key => $val) {
+                               $_GET[$key] = $_REQUEST[$key] = $val;
                        }
                }
        }
        
-       private function extractActionPaths( $paths ) {
-               $url = $_SERVER['REQUEST_URI'];
-               if ( !preg_match( '!^https?://!', $url ) ) {
-                       $url = 'http://unused' . $url;
-               }
-               $a = parse_url( $url );
-               foreach( $paths as $action => $path ) {
+       /**
+        * Internal URL rewriting function; tries to extract page title and,
+        * optionally, one other fixed parameter value from a URL path.
+        *
+        * @param string $path the URL path given from the client
+        * @param array $bases one or more URLs, optionally with $1 at the end
+        * @param string $key if provided, the matching key in $bases will be
+        *        passed on as the value of this URL parameter
+        * @return array of URL variables to interpolate; empty if no match
+        */
+       private function extractTitle( $path, $bases, $key=false ) {
+               foreach( (array)$bases as $keyValue => $base ) {
                        // Find the part after $wgArticlePath
-                       $base = str_replace( '$1', '', $path );
-                       if ( $a && substr( $a['path'], 0, strlen( $base ) ) == $base ) {
-                               return urldecode( substr( $a['path'], strlen( $base ) ) );
+                       $base = str_replace( '$1', '', $base );
+                       $baseLen = strlen( $base );
+                       if( substr( $path, 0, $baseLen ) == $base ) {
+                               $raw = substr( $path, $baseLen );
+                               if( $raw !== '' ) {
+                                       $matches = array( 'title' => urldecode( $raw ) );
+                                       if( $key ) {
+                                               $matches[$key] = $keyValue;
+                                       }
+                                       return $matches;
+                               }
                        }
                }
+               return array();
        }
        
        private $_response;