From: Tim Starling Date: Sun, 2 Jul 2006 15:57:59 +0000 (+0000) Subject: Various performance and initialisation issues: X-Git-Tag: 1.31.0-rc.0~56478 X-Git-Url: http://git.cyclocoop.org/%22%20.%20generer_url_ecrire%28%22auteur_infos%22%2C%20%22id_auteur=%24id%22%29%20.%20%22?a=commitdiff_plain;h=2ff288720c707a0e08a84828f832ea308a63786e;p=lhc%2Fweb%2Fwiklou.git Various performance and initialisation issues: * Made autoloader work for unserialize() * Made XmlFunctions.php and HttpFunctions.php autoloadable modules, via Http:: and Xml:: * Made Image class autoloadable, global functions moved to ImageFunctions.php where they can be loaded on every invocation. * Removed some unnecessary require_once() calls * Deferred $wgValidSkinNames initialisation * Fixed a couple of silly construct/initialise splits. My idea from C++ experience, bad practice in PHP. * Deferred skin initialisation in ParserOptions * Removed $wgMwRedir during an attempt to make MagicWord autoloadable. Didn't complete that, but removing the global is still the right direction. --- diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 6bfbd30bc1..3cf93961a8 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -1,6 +1,9 @@ 'includes/HistoryBlob.php', 'HTMLCacheUpdate' => 'includes/HTMLCacheUpdate.php', 'HTMLCacheUpdateJob' => 'includes/HTMLCacheUpdate.php', + 'Http' => 'includes/HttpFunctions.php', 'Image' => 'includes/Image.php', 'ThumbnailImage' => 'includes/Image.php', 'ImageGallery' => 'includes/ImageGallery.php', @@ -215,6 +219,7 @@ function __autoload($className) { 'WikiError' => 'includes/WikiError.php', 'WikiErrorMsg' => 'includes/WikiError.php', 'WikiXmlError' => 'includes/WikiError.php', + 'Xml' => 'includes/Xml.php', 'ZhClient' => 'includes/ZhClient.php', 'memcached' => 'includes/memcached-client.php', 'UtfNormal' => 'includes/normal/UtfNormal.php' @@ -224,7 +229,19 @@ function __autoload($className) { } elseif ( isset( $wgAutoloadClasses[$className] ) ) { $filename = $wgAutoloadClasses[$className]; } else { - return; + # Try a different capitalisation + # The case can sometimes be wrong when unserializing PHP 4 objects + $filename = false; + $lowerClass = strtolower( $className ); + foreach ( $localClasses as $class2 => $file2 ) { + if ( strtolower( $class2 ) == $lowerClass ) { + $filename = $file2; + } + } + if ( !$filename ) { + # Give up + return; + } } # Make an absolute path, this improves performance by avoiding some stat calls diff --git a/includes/Database.php b/includes/Database.php index 3704ee274c..65ccd58f0b 100644 --- a/includes/Database.php +++ b/includes/Database.php @@ -5,11 +5,6 @@ * @package MediaWiki */ -/** - * Depends on the CacheManager - */ -require_once( 'CacheManager.php' ); - /** See Database::makeList() */ define( 'LIST_COMMA', 0 ); define( 'LIST_AND', 1 ); diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index c907c48cc3..979fc3156b 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -1564,6 +1564,13 @@ $wgExtensionFunctions = array(); */ $wgSkinExtensionFunctions = array(); +/** + * List of valid skin names. + * The key should be the name in all lower case, the value should be a display name. + * The default skins will be added later, by Skin::getSkinNames(). Use + * Skin::getSkinNames() as an accessor if you wish to have access to the full list. + */ +$wgValidSkinNames = array(); /** * Special page list. diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 661b8a6475..0abdda715b 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -1964,4 +1964,14 @@ function wfCreateObject( $name, $p ){ } } +/** + * Aliases for modularized functions + */ +function wfGetHTTP( $url, $timeout = 'default' ) { + return Http::get( $url, $timeout ); +} +function wfIsLocalURL( $url ) { + return Http::isLocalURL( $url ); +} + ?> diff --git a/includes/HttpFunctions.php b/includes/HttpFunctions.php index fd2e87eebd..a9fb13cae9 100644 --- a/includes/HttpFunctions.php +++ b/includes/HttpFunctions.php @@ -1,90 +1,91 @@ getFullURL() ); - } + # 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(); - ob_end_clean(); + ob_start(); + curl_exec( $c ); + $text = ob_get_contents(); + ob_end_clean(); - # Don't return the text of error messages, return false on error - if ( curl_getinfo( $c, CURLINFO_HTTP_CODE ) != 200 ) { - $text = false; + # Don't return the text of error messages, return false on error + if ( curl_getinfo( $c, CURLINFO_HTTP_CODE ) != 200 ) { + $text = false; + } + curl_close( $c ); + } else { + # Otherwise use file_get_contents, or its compatibility function from GlobalFunctions.php + # This may take 3 minutes to time out, and doesn't have local fetch capabilities + $url_fopen = ini_set( 'allow_url_fopen', 1 ); + $text = file_get_contents( $url ); + ini_set( 'allow_url_fopen', $url_fopen ); } - curl_close( $c ); - } else { - # Otherwise use file_get_contents, or its compatibility function from GlobalFunctions.php - # This may take 3 minutes to time out, and doesn't have local fetch capabilities - $url_fopen = ini_set( 'allow_url_fopen', 1 ); - $text = file_get_contents( $url ); - ini_set( 'allow_url_fopen', $url_fopen ); + return $text; } - return $text; -} -/** - * Check if the URL can be served by localhost - */ -function wfIsLocalURL( $url ) { - global $wgCommandLineMode, $wgConf; - if ( $wgCommandLineMode ) { - return false; - } + /** + * Check if the URL can be served by localhost + */ + static function isLocalURL( $url ) { + global $wgCommandLineMode, $wgConf; + if ( $wgCommandLineMode ) { + return false; + } - // Extract host part - $matches = array(); - if ( preg_match( '!^http://([\w.-]+)[/:].*$!', $url, $matches ) ) { - $host = $matches[1]; - // Split up dotwise - $domainParts = explode( '.', $host ); - // Check if this domain or any superdomain is listed in $wgConf as a local virtual host - $domainParts = array_reverse( $domainParts ); - for ( $i = 0; $i < count( $domainParts ); $i++ ) { - $domainPart = $domainParts[$i]; - if ( $i == 0 ) { - $domain = $domainPart; - } else { - $domain = $domainPart . '.' . $domain; - } - if ( $wgConf->isLocalVHost( $domain ) ) { - return true; + // Extract host part + $matches = array(); + if ( preg_match( '!^http://([\w.-]+)[/:].*$!', $url, $matches ) ) { + $host = $matches[1]; + // Split up dotwise + $domainParts = explode( '.', $host ); + // Check if this domain or any superdomain is listed in $wgConf as a local virtual host + $domainParts = array_reverse( $domainParts ); + for ( $i = 0; $i < count( $domainParts ); $i++ ) { + $domainPart = $domainParts[$i]; + if ( $i == 0 ) { + $domain = $domainPart; + } else { + $domain = $domainPart . '.' . $domain; + } + if ( $wgConf->isLocalVHost( $domain ) ) { + return true; + } } } + return false; } - return false; } - ?> diff --git a/includes/Image.php b/includes/Image.php index 16fc55b5ca..ff21c4a064 100644 --- a/includes/Image.php +++ b/includes/Image.php @@ -2165,242 +2165,6 @@ class Image } //class - -/** - * Returns the image directory of an image - * If the directory does not exist, it is created. - * The result is an absolute path. - * - * This function is called from thumb.php before Setup.php is included - * - * @param $fname String: file name of the image file. - * @public - */ -function wfImageDir( $fname ) { - global $wgUploadDirectory, $wgHashedUploadDirectory; - - if (!$wgHashedUploadDirectory) { return $wgUploadDirectory; } - - $hash = md5( $fname ); - $oldumask = umask(0); - $dest = $wgUploadDirectory . '/' . $hash{0}; - if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); } - $dest .= '/' . substr( $hash, 0, 2 ); - if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); } - - umask( $oldumask ); - return $dest; -} - -/** - * Returns the image directory of an image's thubnail - * If the directory does not exist, it is created. - * The result is an absolute path. - * - * This function is called from thumb.php before Setup.php is included - * - * @param $fname String: file name of the original image file - * @param $shared Boolean: (optional) use the shared upload directory (default: 'false'). - * @public - */ -function wfImageThumbDir( $fname, $shared = false ) { - $base = wfImageArchiveDir( $fname, 'thumb', $shared ); - if ( Image::isHashed( $shared ) ) { - $dir = "$base/$fname"; - - if ( !is_dir( $base ) ) { - $oldumask = umask(0); - @mkdir( $base, 0777 ); - umask( $oldumask ); - } - - if ( ! is_dir( $dir ) ) { - if ( is_file( $dir ) ) { - // Old thumbnail in the way of directory creation, kill it - unlink( $dir ); - } - $oldumask = umask(0); - @mkdir( $dir, 0777 ); - umask( $oldumask ); - } - } else { - $dir = $base; - } - - return $dir; -} - -/** - * Old thumbnail directory, kept for conversion - */ -function wfDeprecatedThumbDir( $thumbName , $subdir='thumb', $shared=false) { - return wfImageArchiveDir( $thumbName, $subdir, $shared ); -} - -/** - * Returns the image directory of an image's old version - * If the directory does not exist, it is created. - * The result is an absolute path. - * - * This function is called from thumb.php before Setup.php is included - * - * @param $fname String: file name of the thumbnail file, including file size prefix. - * @param $subdir String: subdirectory of the image upload directory that should be used for storing the old version. Default is 'archive'. - * @param $shared Boolean use the shared upload directory (only relevant for other functions which call this one). Default is 'false'. - * @public - */ -function wfImageArchiveDir( $fname , $subdir='archive', $shared=false ) { - global $wgUploadDirectory, $wgHashedUploadDirectory; - global $wgSharedUploadDirectory, $wgHashedSharedUploadDirectory; - $dir = $shared ? $wgSharedUploadDirectory : $wgUploadDirectory; - $hashdir = $shared ? $wgHashedSharedUploadDirectory : $wgHashedUploadDirectory; - if (!$hashdir) { return $dir.'/'.$subdir; } - $hash = md5( $fname ); - $oldumask = umask(0); - - # Suppress warning messages here; if the file itself can't - # be written we'll worry about it then. - wfSuppressWarnings(); - - $archive = $dir.'/'.$subdir; - if ( ! is_dir( $archive ) ) { mkdir( $archive, 0777 ); } - $archive .= '/' . $hash{0}; - if ( ! is_dir( $archive ) ) { mkdir( $archive, 0777 ); } - $archive .= '/' . substr( $hash, 0, 2 ); - if ( ! is_dir( $archive ) ) { mkdir( $archive, 0777 ); } - - wfRestoreWarnings(); - umask( $oldumask ); - return $archive; -} - - -/* - * Return the hash path component of an image path (URL or filesystem), - * e.g. "/3/3c/", or just "/" if hashing is not used. - * - * @param $dbkey The filesystem / database name of the file - * @param $fromSharedDirectory Use the shared file repository? It may - * use different hash settings from the local one. - */ -function wfGetHashPath ( $dbkey, $fromSharedDirectory = false ) { - if( Image::isHashed( $fromSharedDirectory ) ) { - $hash = md5($dbkey); - return '/' . $hash{0} . '/' . substr( $hash, 0, 2 ) . '/'; - } else { - return '/'; - } -} - -/** - * Returns the image URL of an image's old version - * - * @param $name String: file name of the image file - * @param $subdir String: (optional) subdirectory of the image upload directory that is used by the old version. Default is 'archive' - * @public - */ -function wfImageArchiveUrl( $name, $subdir='archive' ) { - global $wgUploadPath, $wgHashedUploadDirectory; - - if ($wgHashedUploadDirectory) { - $hash = md5( substr( $name, 15) ); - $url = $wgUploadPath.'/'.$subdir.'/' . $hash{0} . '/' . - substr( $hash, 0, 2 ) . '/'.$name; - } else { - $url = $wgUploadPath.'/'.$subdir.'/'.$name; - } - return wfUrlencode($url); -} - -/** - * Return a rounded pixel equivalent for a labeled CSS/SVG length. - * http://www.w3.org/TR/SVG11/coords.html#UnitIdentifiers - * - * @param $length String: CSS/SVG length. - * @return Integer: length in pixels - */ -function wfScaleSVGUnit( $length ) { - static $unitLength = array( - 'px' => 1.0, - 'pt' => 1.25, - 'pc' => 15.0, - 'mm' => 3.543307, - 'cm' => 35.43307, - 'in' => 90.0, - '' => 1.0, // "User units" pixels by default - '%' => 2.0, // Fake it! - ); - if( preg_match( '/^(\d+(?:\.\d+)?)(em|ex|px|pt|pc|cm|mm|in|%|)$/', $length, $matches ) ) { - $length = floatval( $matches[1] ); - $unit = $matches[2]; - return round( $length * $unitLength[$unit] ); - } else { - // Assume pixels - return round( floatval( $length ) ); - } -} - -/** - * Compatible with PHP getimagesize() - * @todo support gzipped SVGZ - * @todo check XML more carefully - * @todo sensible defaults - * - * @param $filename String: full name of the file (passed to php fopen()). - * @return array - */ -function wfGetSVGsize( $filename ) { - $width = 256; - $height = 256; - - // Read a chunk of the file - $f = fopen( $filename, "rt" ); - if( !$f ) return false; - $chunk = fread( $f, 4096 ); - fclose( $f ); - - // Uber-crappy hack! Run through a real XML parser. - if( !preg_match( '/]*)\s*>/s', $chunk, $matches ) ) { - return false; - } - $tag = $matches[1]; - if( preg_match( '/\bwidth\s*=\s*("[^"]+"|\'[^\']+\')/s', $tag, $matches ) ) { - $width = wfScaleSVGUnit( trim( substr( $matches[1], 1, -1 ) ) ); - } - if( preg_match( '/\bheight\s*=\s*("[^"]+"|\'[^\']+\')/s', $tag, $matches ) ) { - $height = wfScaleSVGUnit( trim( substr( $matches[1], 1, -1 ) ) ); - } - - return array( $width, $height, 'SVG', - "width=\"$width\" height=\"$height\"" ); -} - -/** - * Determine if an image exists on the 'bad image list'. - * - * @param $name String: the image name to check - * @return bool - */ -function wfIsBadImage( $name ) { - static $titleList = false; - - if( !$titleList ) { - # Build the list now - $titleList = array(); - $lines = explode( "\n", wfMsgForContent( 'bad_image_list' ) ); - foreach( $lines as $line ) { - if( preg_match( '/^\*\s*\[\[:?(.*?)\]\]/i', $line, $matches ) ) { - $title = Title::newFromText( $matches[1] ); - if( is_object( $title ) && $title->getNamespace() == NS_IMAGE ) - $titleList[ $title->getDBkey() ] = true; - } - } - } - return array_key_exists( $name, $titleList ); -} - - - /** * Wrapper class for thumbnail images * @package MediaWiki @@ -2456,21 +2220,4 @@ class ThumbnailImage { } -/** - * Calculate the largest thumbnail width for a given original file size - * such that the thumbnail's height is at most $maxHeight. - * @param $boxWidth Integer Width of the thumbnail box. - * @param $boxHeight Integer Height of the thumbnail box. - * @param $maxHeight Integer Maximum height expected for the thumbnail. - * @return Integer. - */ -function wfFitBoxWidth( $boxWidth, $boxHeight, $maxHeight ) { - $idealWidth = $boxWidth * $maxHeight / $boxHeight; - $roundedUp = ceil( $idealWidth ); - if( round( $roundedUp * $boxHeight / $boxWidth ) > $maxHeight ) - return floor( $idealWidth ); - else - return $roundedUp; -} - ?> diff --git a/includes/ImageFunctions.php b/includes/ImageFunctions.php new file mode 100644 index 0000000000..c031d7ef7f --- /dev/null +++ b/includes/ImageFunctions.php @@ -0,0 +1,254 @@ + 1.0, + 'pt' => 1.25, + 'pc' => 15.0, + 'mm' => 3.543307, + 'cm' => 35.43307, + 'in' => 90.0, + '' => 1.0, // "User units" pixels by default + '%' => 2.0, // Fake it! + ); + if( preg_match( '/^(\d+(?:\.\d+)?)(em|ex|px|pt|pc|cm|mm|in|%|)$/', $length, $matches ) ) { + $length = floatval( $matches[1] ); + $unit = $matches[2]; + return round( $length * $unitLength[$unit] ); + } else { + // Assume pixels + return round( floatval( $length ) ); + } +} + +/** + * Compatible with PHP getimagesize() + * @todo support gzipped SVGZ + * @todo check XML more carefully + * @todo sensible defaults + * + * @param $filename String: full name of the file (passed to php fopen()). + * @return array + */ +function wfGetSVGsize( $filename ) { + $width = 256; + $height = 256; + + // Read a chunk of the file + $f = fopen( $filename, "rt" ); + if( !$f ) return false; + $chunk = fread( $f, 4096 ); + fclose( $f ); + + // Uber-crappy hack! Run through a real XML parser. + if( !preg_match( '/]*)\s*>/s', $chunk, $matches ) ) { + return false; + } + $tag = $matches[1]; + if( preg_match( '/\bwidth\s*=\s*("[^"]+"|\'[^\']+\')/s', $tag, $matches ) ) { + $width = wfScaleSVGUnit( trim( substr( $matches[1], 1, -1 ) ) ); + } + if( preg_match( '/\bheight\s*=\s*("[^"]+"|\'[^\']+\')/s', $tag, $matches ) ) { + $height = wfScaleSVGUnit( trim( substr( $matches[1], 1, -1 ) ) ); + } + + return array( $width, $height, 'SVG', + "width=\"$width\" height=\"$height\"" ); +} + +/** + * Determine if an image exists on the 'bad image list'. + * + * @param $name String: the image name to check + * @return bool + */ +function wfIsBadImage( $name ) { + static $titleList = false; + + if( !$titleList ) { + # Build the list now + $titleList = array(); + $lines = explode( "\n", wfMsgForContent( 'bad_image_list' ) ); + foreach( $lines as $line ) { + if( preg_match( '/^\*\s*\[\[:?(.*?)\]\]/i', $line, $matches ) ) { + $title = Title::newFromText( $matches[1] ); + if( is_object( $title ) && $title->getNamespace() == NS_IMAGE ) + $titleList[ $title->getDBkey() ] = true; + } + } + } + return array_key_exists( $name, $titleList ); +} + +/** + * Calculate the largest thumbnail width for a given original file size + * such that the thumbnail's height is at most $maxHeight. + * @param $boxWidth Integer Width of the thumbnail box. + * @param $boxHeight Integer Height of the thumbnail box. + * @param $maxHeight Integer Maximum height expected for the thumbnail. + * @return Integer. + */ +function wfFitBoxWidth( $boxWidth, $boxHeight, $maxHeight ) { + $idealWidth = $boxWidth * $maxHeight / $boxHeight; + $roundedUp = ceil( $idealWidth ); + if( round( $roundedUp * $boxHeight / $boxWidth ) > $maxHeight ) + return floor( $idealWidth ); + else + return $roundedUp; +} + + +?> diff --git a/includes/MessageCache.php b/includes/MessageCache.php index e5035c58a7..1247f3fb6e 100644 --- a/includes/MessageCache.php +++ b/includes/MessageCache.php @@ -25,7 +25,7 @@ class MessageCache { var $mInitialised = false; var $mDeferred = true; - function initialise( &$memCached, $useDB, $expiry, $memcPrefix) { + function __construct( &$memCached, $useDB, $expiry, $memcPrefix) { $fname = 'MessageCache::initialise'; wfProfileIn( $fname ); @@ -39,7 +39,7 @@ class MessageCache { $this->mInitialised = true; wfProfileIn( $fname.'-parseropt' ); - $this->mParserOptions = ParserOptions::newFromUser( $u=NULL ); + $this->mParserOptions = new ParserOptions( $u=NULL ); wfProfileOut( $fname.'-parseropt' ); wfProfileIn( $fname.'-parser' ); $this->mParser = new Parser; @@ -558,9 +558,11 @@ class MessageCache { * @param string $lang The messages language, English by default */ function addMessages( $messages, $lang = 'en' ) { + wfProfileIn( __METHOD__ ); foreach ( $messages as $key => $value ) { $this->addMessage( $key, $value, $lang ); } + wfProfileOut( __METHOD__ ); } /** diff --git a/includes/Parser.php b/includes/Parser.php index 2fde2df9da..ec4349b82b 100644 --- a/includes/Parser.php +++ b/includes/Parser.php @@ -6,10 +6,6 @@ * @subpackage Parser */ -/** */ -require_once( 'Sanitizer.php' ); -require_once( 'HttpFunctions.php' ); - /** * Update this version number when the ParserOutput format * changes in an incompatible way, so the parser cache @@ -3165,7 +3161,7 @@ class Parser } } - $text = wfGetHTTP($url); + $text = Http::get($url); if (!$text) return wfMsg('scarytranscludefailed', $url); @@ -4605,12 +4601,13 @@ class ParserOptions var $mTidy; # Ask for tidy cleanup var $mInterfaceMessage; # Which lang to call for PLURAL and GRAMMAR + var $mUser; # Stored user object, just used to initialise the skin + function getUseTeX() { return $this->mUseTeX; } function getUseDynamicDates() { return $this->mUseDynamicDates; } function getInterwikiMagic() { return $this->mInterwikiMagic; } function getAllowExternalImages() { return $this->mAllowExternalImages; } function getAllowExternalImagesFrom() { return $this->mAllowExternalImagesFrom; } - function &getSkin() { return $this->mSkin; } function getDateFormat() { return $this->mDateFormat; } function getEditSection() { return $this->mEditSection; } function getNumberHeadings() { return $this->mNumberHeadings; } @@ -4618,6 +4615,13 @@ class ParserOptions function getTidy() { return $this->mTidy; } function getInterfaceMessage() { return $this->mInterfaceMessage; } + function &getSkin() { + if ( !isset( $this->mSkin ) ) { + $this->mSkin = $this->mUser->getSkin(); + } + return $this->mSkin; + } + function setUseTeX( $x ) { return wfSetVar( $this->mUseTeX, $x ); } function setUseDynamicDates( $x ) { return wfSetVar( $this->mUseDynamicDates, $x ); } function setInterwikiMagic( $x ) { return wfSetVar( $this->mInterwikiMagic, $x ); } @@ -4631,9 +4635,8 @@ class ParserOptions function setSkin( &$x ) { $this->mSkin =& $x; } function setInterfaceMessage( $x ) { return wfSetVar( $this->mInterfaceMessage, $x); } - function ParserOptions() { - global $wgUser; - $this->initialiseFromUser( $wgUser ); + function ParserOptions( $user = null ) { + $this->initialiseFromUser( $user ); } /** @@ -4641,9 +4644,7 @@ class ParserOptions * @static */ function newFromUser( &$user ) { - $popts = new ParserOptions; - $popts->initialiseFromUser( $user ); - return $popts; + return new ParserOptions( $user ); } /** Get user options */ @@ -4653,20 +4654,25 @@ class ParserOptions $fname = 'ParserOptions::initialiseFromUser'; wfProfileIn( $fname ); if ( !$userInput ) { - $user = new User; - $user->setLoaded( true ); + global $wgUser; + if ( isset( $wgUser ) ) { + $user = $wgUser; + } else { + $user = new User; + $user->setLoaded( true ); + } } else { $user =& $userInput; } + $this->mUser = $user; + $this->mUseTeX = $wgUseTeX; $this->mUseDynamicDates = $wgUseDynamicDates; $this->mInterwikiMagic = $wgInterwikiMagic; $this->mAllowExternalImages = $wgAllowExternalImages; $this->mAllowExternalImagesFrom = $wgAllowExternalImagesFrom; - wfProfileIn( $fname.'-skin' ); - $this->mSkin =& $user->getSkin(); - wfProfileOut( $fname.'-skin' ); + $this->mSkin = null; # Deferred $this->mDateFormat = $user->getOption( 'date' ); $this->mEditSection = true; $this->mNumberHeadings = $user->getOption( 'numberheadings' ); diff --git a/includes/Setup.php b/includes/Setup.php index c2e89f20a7..469a69195f 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -56,16 +56,14 @@ require_once( "$IP/includes/GlobalFunctions.php" ); require_once( "$IP/includes/Hooks.php" ); require_once( "$IP/includes/Namespace.php" ); require_once( "$IP/includes/User.php" ); -require_once( "$IP/includes/Skin.php" ); require_once( "$IP/includes/OutputPage.php" ); require_once( "$IP/includes/MagicWord.php" ); -require_once( "$IP/includes/Block.php" ); require_once( "$IP/includes/MessageCache.php" ); require_once( "$IP/includes/Parser.php" ); require_once( "$IP/includes/LoadBalancer.php" ); -require_once( "$IP/includes/HistoryBlob.php" ); require_once( "$IP/includes/ProxyTools.php" ); require_once( "$IP/includes/ObjectCache.php" ); +require_once( "$IP/includes/ImageFunctions.php" ); if ( $wgUseDynamicDates ) { require_once( "$IP/includes/DateFormatter.php" ); @@ -254,8 +252,7 @@ if( $wgLangClass == $wgContLangClass ) { wfProfileOut( $fname.'-language2' ); wfProfileIn( $fname.'-MessageCache' ); -$wgMessageCache = new MessageCache; -$wgMessageCache->initialise( $parserMemc, $wgUseDatabaseMessages, $wgMsgCacheExpiry, $wgDBname); +$wgMessageCache = new MessageCache( $parserMemc, $wgUseDatabaseMessages, $wgMsgCacheExpiry, $wgDBname); wfProfileOut( $fname.'-MessageCache' ); @@ -292,7 +289,6 @@ $wgDeferredUpdateList = array(); $wgPostCommitUpdateList = array(); $wgMagicWords = array(); -$wgMwRedir =& MagicWord::get( MAG_REDIRECT ); if ( $wgUseXMLparser ) { require_once( 'ParserXML.php' ); diff --git a/includes/Skin.php b/includes/Skin.php index 6705fae9d1..8a03f461ff 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -9,26 +9,6 @@ if ( ! defined( 'MEDIAWIKI' ) ) */ # See skin.txt -require_once( 'Linker.php' ); -require_once( 'Image.php' ); - -# Get a list of available skins -# Build using the regular expression '^(.*).php$' -# Array keys are all lower case, array value keep the case used by filename -# - -$skinDir = dir( $wgStyleDirectory ); - -# while code from www.php.net -while (false !== ($file = $skinDir->read())) { - // Skip non-PHP files, hidden files, and '.dep' includes - if(preg_match('/^([^.]*)\.php$/',$file, $matches)) { - $aSkin = $matches[1]; - $wgValidSkinNames[strtolower($aSkin)] = $aSkin; - } -} -$skinDir->close(); -unset($matches); /** * The main skin class that provide methods and properties for all other skins. @@ -53,8 +33,30 @@ class Skin extends Linker { * @return array of strings * @static */ - function getSkinNames() { + function &getSkinNames() { global $wgValidSkinNames; + static $skinsInitialised = false; + if ( !$skinsInitialised ) { + # Get a list of available skins + # Build using the regular expression '^(.*).php$' + # Array keys are all lower case, array value keep the case used by filename + # + wfProfileIn( __METHOD__ . '-init' ); + global $wgStyleDirectory; + $skinDir = dir( $wgStyleDirectory ); + + # while code from www.php.net + while (false !== ($file = $skinDir->read())) { + // Skip non-PHP files, hidden files, and '.dep' includes + if(preg_match('/^([^.]*)\.php$/',$file, $matches)) { + $aSkin = $matches[1]; + $wgValidSkinNames[strtolower($aSkin)] = $aSkin; + } + } + $skinDir->close(); + $skinsInitialised = true; + wfProfileOut( __METHOD__ . '-init' ); + } return $wgValidSkinNames; } diff --git a/includes/SpecialPage.php b/includes/SpecialPage.php index 10beb276b9..ffcd51fa92 100644 --- a/includes/SpecialPage.php +++ b/includes/SpecialPage.php @@ -143,8 +143,6 @@ class SpecialPage global $wgSpecialPages; global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication; - #throw new MWException( __METHOD__ ); - if ( self::$mListInitialised ) { return; } diff --git a/includes/SpecialPreferences.php b/includes/SpecialPreferences.php index 114901e95f..5411db4c74 100644 --- a/includes/SpecialPreferences.php +++ b/includes/SpecialPreferences.php @@ -447,7 +447,7 @@ class PreferencesForm { * @access private */ function mainPrefsForm( $status , $message = '' ) { - global $wgUser, $wgOut, $wgLang, $wgContLang, $wgValidSkinNames; + global $wgUser, $wgOut, $wgLang, $wgContLang; global $wgAllowRealName, $wgImageLimits, $wgThumbLimits; global $wgDisableLangConversion; global $wgEnotifWatchlist, $wgEnotifUserTalk,$wgEnotifMinorEdits; @@ -728,9 +728,10 @@ class PreferencesForm { $wgOut->addHTML( "
\n\n" . wfMsg('skin') . "\n" ); $mptitle = Title::newMainPage(); $previewtext = wfMsg('skinpreview'); - # Only show members of $wgValidSkinNames rather than + # Only show members of Skin::getSkinNames() rather than # $skinNames (skins is all skin names from Language.php) - foreach ($wgValidSkinNames as $skinkey => $skinname ) { + $validSkinNames = Skin::getSkinNames(); + foreach ($validSkinNames as $skinkey => $skinname ) { if ( in_array( $skinkey, $wgSkipSkins ) ) { continue; } diff --git a/includes/Title.php b/includes/Title.php index 535b07674a..bc8f69a2b2 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -286,9 +286,9 @@ class Title { * @access public */ function newFromRedirect( $text ) { - global $wgMwRedir; + $mwRedir = MagicWord::get( MAG_REDIRECT ); $rt = NULL; - if ( $wgMwRedir->matchStart( $text ) ) { + if ( $mwRedir->matchStart( $text ) ) { if ( preg_match( '/\[{2}(.*?)(?:\||\]{2})/', $text, $m ) ) { # categories are escaped using : for example one can enter: # #REDIRECT [[:Category:Music]]. Need to remove it. @@ -1187,8 +1187,12 @@ class Title { * Check that the corresponding skin exists */ function isValidCssJsSubpage() { - global $wgValidSkinNames; - return( $this->isCssJsSubpage() && array_key_exists( $this->getSkinFromCssJsSubpage(), $wgValidSkinNames ) ); + if ( $this->isCssJsSubpage() ) { + $skinNames = Skin::getSkinNames(); + return array_key_exists( $this->getSkinFromCssJsSubpage(), $skinNames ); + } else { + return false; + } } /** * Trim down a .css or .js subpage title to get the corresponding skin name @@ -1854,7 +1858,7 @@ class Title { * @private */ function moveOverExistingRedirect( &$nt, $reason = '' ) { - global $wgUseSquid, $wgMwRedir; + global $wgUseSquid; $fname = 'Title::moveOverExistingRedirect'; $comment = wfMsgForContent( '1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() ); @@ -1893,7 +1897,8 @@ class Title { $linkCache->clearLink( $nt->getPrefixedDBkey() ); # Recreate the redirect, this time in the other direction. - $redirectText = $wgMwRedir->getSynonym( 0 ) . ' [[' . $nt->getPrefixedText() . "]]\n"; + $mwRedir = MagicWord::get( MAG_REDIRECT ); + $redirectText = $mwRedir->getSynonym( 0 ) . ' [[' . $nt->getPrefixedText() . "]]\n"; $redirectArticle = new Article( $this ); $newid = $redirectArticle->insertOn( $dbw ); $redirectRevision = new Revision( array( @@ -1933,7 +1938,6 @@ class Title { */ function moveToNewTitle( &$nt, $reason = '' ) { global $wgUseSquid; - global $wgMwRedir; $fname = 'MovePageForm::moveToNewTitle'; $comment = wfMsgForContent( '1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() ); if ( $reason ) { @@ -1966,7 +1970,8 @@ class Title { $linkCache->clearLink( $nt->getPrefixedDBkey() ); # Insert redirect - $redirectText = $wgMwRedir->getSynonym( 0 ) . ' [[' . $nt->getPrefixedText() . "]]\n"; + $mwRedir = MagicWord::get( MAG_REDIRECT ); + $redirectText = $mwRedir->getSynonym( 0 ) . ' [[' . $nt->getPrefixedText() . "]]\n"; $redirectArticle = new Article( $this ); $newid = $redirectArticle->insertOn( $dbw ); $redirectRevision = new Revision( array( diff --git a/includes/Xml.php b/includes/Xml.php new file mode 100644 index 0000000000..f911bdcec4 --- /dev/null +++ b/includes/Xml.php @@ -0,0 +1,279 @@ +, &) are escaped but illegals are not touched. + * + * @param $element String: + * @param $attribs Array: Name=>value pairs. Values will be escaped. + * @param $contents String: NULL to make an open tag only; '' for a contentless closed tag (default) + * @return string + */ + function element( $element, $attribs = null, $contents = '') { + $out = '<' . $element; + if( !is_null( $attribs ) ) { + foreach( $attribs as $name => $val ) { + $out .= ' ' . $name . '="' . htmlspecialchars( $val ) . '"'; + } + } + if( is_null( $contents ) ) { + $out .= '>'; + } else { + if( $contents === '' ) { + $out .= ' />'; + } else { + $out .= '>' . htmlspecialchars( $contents ) . ""; + } + } + return $out; + } + + /** + * Format an XML element as with self::element(), but run text through the + * UtfNormal::cleanUp() validator first to ensure that no invalid UTF-8 + * is passed. + * + * @param $element String: + * @param $attribs Array: Name=>value pairs. Values will be escaped. + * @param $contents String: NULL to make an open tag only; '' for a contentless closed tag (default) + * @return string + */ + function elementClean( $element, $attribs = array(), $contents = '') { + if( $attribs ) { + $attribs = array_map( array( 'UtfNormal', 'cleanUp' ), $attribs ); + } + if( $contents ) { + $contents = UtfNormal::cleanUp( $contents ); + } + return self::element( $element, $attribs, $contents ); + } + + // Shortcuts + function openElement( $element, $attribs = null ) { return self::element( $element, $attribs, null ); } + function closeElement( $element ) { return ""; } + + /** + * Create a namespace selector + * + * @param $selected Mixed: the namespace which should be selected, default '' + * @param $allnamespaces String: value of a special item denoting all namespaces. Null to not include (default) + * @param $includehidden Bool: include hidden namespaces? + * @return String: Html string containing the namespace selector + */ + function &namespaceSelector($selected = '', $allnamespaces = null, $includehidden=false) { + global $wgContLang; + if( $selected !== '' ) { + if( is_null( $selected ) ) { + // No namespace selected; let exact match work without hitting Main + $selected = ''; + } else { + // Let input be numeric strings without breaking the empty match. + $selected = intval( $selected ); + } + } + $s = "\n"; + return $s; + } + + function span( $text, $class, $attribs=array() ) { + return self::element( 'span', array( 'class' => $class ) + $attribs, $text ); + } + + /** + * Convenience function to build an HTML text input field + * @return string HTML + */ + function input( $name, $size=false, $value=false, $attribs=array() ) { + return self::element( 'input', array( + 'name' => $name, + 'size' => $size, + 'value' => $value ) + $attribs ); + } + + /** + * Internal function for use in checkboxes and radio buttons and such. + * @return array + */ + function attrib( $name, $present = true ) { + return $present ? array( $name => $name ) : array(); + } + + /** + * Convenience function to build an HTML checkbox + * @return string HTML + */ + function check( $name, $checked=false, $attribs=array() ) { + return self::element( 'input', array( + 'name' => $name, + 'type' => 'checkbox', + 'value' => 1 ) + self::attrib( 'checked', $checked ) + $attribs ); + } + + /** + * Convenience function to build an HTML radio button + * @return string HTML + */ + function radio( $name, $value, $checked=false, $attribs=array() ) { + return self::element( 'input', array( + 'name' => $name, + 'type' => 'radio', + 'value' => $value ) + self::attrib( 'checked', $checked ) + $attribs ); + } + + /** + * Convenience function to build an HTML form label + * @return string HTML + */ + function label( $label, $id ) { + return self::element( 'label', array( 'for' => $id ), $label ); + } + + /** + * Convenience function to build an HTML text input field with a label + * @return string HTML + */ + function inputLabel( $label, $name, $id, $size=false, $value=false, $attribs=array() ) { + return Xml::label( $label, $id ) . + ' ' . + self::input( $name, $size, $value, array( 'id' => $id ) + $attribs ); + } + + /** + * Convenience function to build an HTML checkbox with a label + * @return string HTML + */ + function checkLabel( $label, $name, $id, $checked=false, $attribs=array() ) { + return self::check( $name, $checked, array( 'id' => $id ) + $attribs ) . + ' ' . + self::label( $label, $id ); + } + + /** + * Convenience function to build an HTML radio button with a label + * @return string HTML + */ + function radioLabel( $label, $name, $value, $id, $checked=false, $attribs=array() ) { + return self::radio( $name, $value, $checked, array( 'id' => $id ) + $attribs ) . + ' ' . + self::label( $label, $id ); + } + + /** + * Convenience function to build an HTML submit button + * @param $value String: label text for the button + * @param $attribs Array: optional custom attributes + * @return string HTML + */ + function submitButton( $value, $attribs=array() ) { + return self::element( 'input', array( 'type' => 'submit', 'value' => $value ) + $attribs ); + } + + /** + * Convenience function to build an HTML hidden form field. + * @todo Document $name parameter. + * @param $name FIXME + * @param $value String: label text for the button + * @param $attribs Array: optional custom attributes + * @return string HTML + */ + function hidden( $name, $value, $attribs=array() ) { + return self::element( 'input', array( + 'name' => $name, + 'type' => 'hidden', + 'value' => $value ) + $attribs ); + } + + /** + * Returns an escaped string suitable for inclusion in a string literal + * for JavaScript source code. + * Illegal control characters are assumed not to be present. + * + * @param string $string + * @return string + */ + function escapeJsString( $string ) { + // See ECMA 262 section 7.8.4 for string literal format + $pairs = array( + "\\" => "\\\\", + "\"" => "\\\"", + '\'' => '\\\'', + "\n" => "\\n", + "\r" => "\\r", + + # To avoid closing the element or CDATA section + "<" => "\\x3c", + ">" => "\\x3e", + ); + return strtr( $string, $pairs ); + } + + /** + * Check if a string is well-formed XML. + * Must include the surrounding tag. + * + * @param $text String: string to test. + * @return bool + * + * @todo Error position reporting return + */ + function isWellFormed( $text ) { + $parser = xml_parser_create( "UTF-8" ); + + # case folding violates XML standard, turn it off + xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false ); + + if( !xml_parse( $parser, $text, true ) ) { + $err = xml_error_string( xml_get_error_code( $parser ) ); + $position = xml_get_current_byte_index( $parser ); + //$fragment = $this->extractFragment( $html, $position ); + //$this->mXmlError = "$err at byte $position:\n$fragment"; + xml_parser_free( $parser ); + return false; + } + xml_parser_free( $parser ); + return true; + } + + /** + * Check if a string is a well-formed XML fragment. + * Wraps fragment in an \ bit and doctype, so it can be a fragment + * and can use HTML named entities. + * + * @param $text String: + * @return bool + */ + function isWellFormedXmlFragment( $text ) { + $html = + Sanitizer::hackDocType() . + '' . + $text . + ''; + return Xml::isWellFormedXml( $html ); + } +} +?> diff --git a/includes/XmlFunctions.php b/includes/XmlFunctions.php index caec564ae5..7bb2895aaa 100644 --- a/includes/XmlFunctions.php +++ b/includes/XmlFunctions.php @@ -1,274 +1,64 @@ , &) are escaped but illegals are not touched. - * - * @param $element String: - * @param $attribs Array: Name=>value pairs. Values will be escaped. - * @param $contents String: NULL to make an open tag only; '' for a contentless closed tag (default) - * @return string + * Aliases for functions in the Xml module */ -function wfElement( $element, $attribs = null, $contents = '') { - $out = '<' . $element; - if( !is_null( $attribs ) ) { - foreach( $attribs as $name => $val ) { - $out .= ' ' . $name . '="' . htmlspecialchars( $val ) . '"'; - } - } - if( is_null( $contents ) ) { - $out .= '>'; - } else { - if( $contents === '' ) { - $out .= ' />'; - } else { - $out .= '>' . htmlspecialchars( $contents ) . ""; - } - } - return $out; +function wfElement( $element, $attribs = null, $contents = '') { + return Xml::element( $element, $attribs, $contents ); } - -/** - * Format an XML element as with wfElement(), but run text through the - * UtfNormal::cleanUp() validator first to ensure that no invalid UTF-8 - * is passed. - * - * @param $element String: - * @param $attribs Array: Name=>value pairs. Values will be escaped. - * @param $contents String: NULL to make an open tag only; '' for a contentless closed tag (default) - * @return string - */ function wfElementClean( $element, $attribs = array(), $contents = '') { - if( $attribs ) { - $attribs = array_map( array( 'UtfNormal', 'cleanUp' ), $attribs ); - } - if( $contents ) { - $contents = UtfNormal::cleanUp( $contents ); - } - return wfElement( $element, $attribs, $contents ); + return Xml::elementClean( $element, $attribs, $contents ); +} +function wfOpenElement( $element, $attribs = null ) { + return Xml::openElement( $element, $attribs ); +} +function wfCloseElement( $element ) { + return ""; } - -// Shortcuts -function wfOpenElement( $element, $attribs = null ) { return wfElement( $element, $attribs, null ); } -function wfCloseElement( $element ) { return ""; } - -/** - * Create a namespace selector - * - * @param $selected Mixed: the namespace which should be selected, default '' - * @param $allnamespaces String: value of a special item denoting all namespaces. Null to not include (default) - * @param $includehidden Bool: include hidden namespaces? - * @return String: Html string containing the namespace selector - */ function &HTMLnamespaceselector($selected = '', $allnamespaces = null, $includehidden=false) { - global $wgContLang; - if( $selected !== '' ) { - if( is_null( $selected ) ) { - // No namespace selected; let exact match work without hitting Main - $selected = ''; - } else { - // Let input be numeric strings without breaking the empty match. - $selected = intval( $selected ); - } - } - $s = "\n"; - return $s; + return Xml::namespaceSelector( $selected = '', $allnamespaces = null, $includehidden=false ); } - function wfSpan( $text, $class, $attribs=array() ) { - return wfElement( 'span', array( 'class' => $class ) + $attribs, $text ); + return Xml::span( $text, $class, $attribs ); } - -/** - * Convenience function to build an HTML text input field - * @return string HTML - */ function wfInput( $name, $size=false, $value=false, $attribs=array() ) { - return wfElement( 'input', array( - 'name' => $name, - 'size' => $size, - 'value' => $value ) + $attribs ); + return Xml::input( $name, $size, $value, $attribs ); } - -/** - * Internal function for use in checkboxes and radio buttons and such. - * @return array - */ function wfAttrib( $name, $present = true ) { - return $present ? array( $name => $name ) : array(); + return Xml::attrib( $name, $present ); } - -/** - * Convenience function to build an HTML checkbox - * @return string HTML - */ function wfCheck( $name, $checked=false, $attribs=array() ) { - return wfElement( 'input', array( - 'name' => $name, - 'type' => 'checkbox', - 'value' => 1 ) + wfAttrib( 'checked', $checked ) + $attribs ); + return Xml::check( $name, $checked, $attribs ); } - -/** - * Convenience function to build an HTML radio button - * @return string HTML - */ function wfRadio( $name, $value, $checked=false, $attribs=array() ) { - return wfElement( 'input', array( - 'name' => $name, - 'type' => 'radio', - 'value' => $value ) + wfAttrib( 'checked', $checked ) + $attribs ); + return Xml::radio( $name, $value, $checked, $attribs ); } - -/** - * Convenience function to build an HTML form label - * @return string HTML - */ function wfLabel( $label, $id ) { - return wfElement( 'label', array( 'for' => $id ), $label ); + return Xml::label( $label, $id ); } - -/** - * Convenience function to build an HTML text input field with a label - * @return string HTML - */ function wfInputLabel( $label, $name, $id, $size=false, $value=false, $attribs=array() ) { - return wfLabel( $label, $id ) . - ' ' . - wfInput( $name, $size, $value, array( 'id' => $id ) + $attribs ); + return Xml::inputLabel( $label, $name, $id, $size, $value, $attribs ); } - -/** - * Convenience function to build an HTML checkbox with a label - * @return string HTML - */ function wfCheckLabel( $label, $name, $id, $checked=false, $attribs=array() ) { - return wfCheck( $name, $checked, array( 'id' => $id ) + $attribs ) . - ' ' . - wfLabel( $label, $id ); + return Xml::checkLabel( $label, $name, $id, $checked, $attribs ); } - -/** - * Convenience function to build an HTML radio button with a label - * @return string HTML - */ function wfRadioLabel( $label, $name, $value, $id, $checked=false, $attribs=array() ) { - return wfRadio( $name, $value, $checked, array( 'id' => $id ) + $attribs ) . - ' ' . - wfLabel( $label, $id ); + return Xml::radioLabel( $label, $name, $value, $id, $checked, $attribs ); } - -/** - * Convenience function to build an HTML submit button - * @param $value String: label text for the button - * @param $attribs Array: optional custom attributes - * @return string HTML - */ function wfSubmitButton( $value, $attribs=array() ) { - return wfElement( 'input', array( 'type' => 'submit', 'value' => $value ) + $attribs ); + return Xml::submitButton( $value, $attribs ); } - -/** - * Convenience function to build an HTML hidden form field. - * @todo Document $name parameter. - * @param $name FIXME - * @param $value String: label text for the button - * @param $attribs Array: optional custom attributes - * @return string HTML - */ function wfHidden( $name, $value, $attribs=array() ) { - return wfElement( 'input', array( - 'name' => $name, - 'type' => 'hidden', - 'value' => $value ) + $attribs ); + return Xml::hidden( $name, $value, $attribs ); } - -/** - * Returns an escaped string suitable for inclusion in a string literal - * for JavaScript source code. - * Illegal control characters are assumed not to be present. - * - * @param string $string - * @return string - */ function wfEscapeJsString( $string ) { - // See ECMA 262 section 7.8.4 for string literal format - $pairs = array( - "\\" => "\\\\", - "\"" => "\\\"", - '\'' => '\\\'', - "\n" => "\\n", - "\r" => "\\r", - - # To avoid closing the element or CDATA section - "<" => "\\x3c", - ">" => "\\x3e", - ); - return strtr( $string, $pairs ); + return Xml::escapeJsString( $string ); } - -/** - * Check if a string is well-formed XML. - * Must include the surrounding tag. - * - * @param $text String: string to test. - * @return bool - * - * @todo Error position reporting return - */ function wfIsWellFormedXml( $text ) { - $parser = xml_parser_create( "UTF-8" ); - - # case folding violates XML standard, turn it off - xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false ); - - if( !xml_parse( $parser, $text, true ) ) { - $err = xml_error_string( xml_get_error_code( $parser ) ); - $position = xml_get_current_byte_index( $parser ); - //$fragment = $this->extractFragment( $html, $position ); - //$this->mXmlError = "$err at byte $position:\n$fragment"; - xml_parser_free( $parser ); - return false; - } - xml_parser_free( $parser ); - return true; + return Xml::isWellFormed( $text ); } - -/** - * Check if a string is a well-formed XML fragment. - * Wraps fragment in an \ bit and doctype, so it can be a fragment - * and can use HTML named entities. - * - * @param $text String: - * @return bool - */ function wfIsWellFormedXmlFragment( $text ) { - $html = - Sanitizer::hackDocType() . - '' . - $text . - ''; - return wfIsWellFormedXml( $html ); + return Xml::isWellFormedXmlFragment( $text ); } diff --git a/maintenance/parserTests.inc b/maintenance/parserTests.inc index 3e1b2fd489..9f93c4ac66 100644 --- a/maintenance/parserTests.inc +++ b/maintenance/parserTests.inc @@ -360,7 +360,7 @@ class ParserTest { $GLOBALS['wgContLang'] = $langObj; $GLOBALS['wgLoadBalancer']->loadMasterPos(); - $GLOBALS['wgMessageCache']->initialise( new BagOStuff(), false, 0, $GLOBALS['wgDBname'] ); + $GLOBALS['wgMessageCache'] = new MessageCache( new BagOStuff(), false, 0, $GLOBALS['wgDBname'] ); $this->setupDatabase(); global $wgUser;