From d9d553fa98ee9a2fe43c07d5742f3cec7acf777a Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 17 May 2007 20:02:59 +0000 Subject: [PATCH] Fix for regression in variant short-URLs... 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 | 4 ++ includes/WebRequest.php | 95 +++++++++++++++++++++++++++++++---------- 2 files changed, 76 insertions(+), 23 deletions(-) diff --git a/includes/Setup.php b/includes/Setup.php index 47ba494f60..7f964a1d21 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -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' ); diff --git a/includes/WebRequest.php b/includes/WebRequest.php index 1a59766e7b..5ba1203f02 100644 --- a/includes/WebRequest.php +++ b/includes/WebRequest.php @@ -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; -- 2.20.1