diff options
author | Tim Starling <tstarling@users.mediawiki.org> | 2006-11-21 09:53:45 +0000 |
---|---|---|
committer | Tim Starling <tstarling@users.mediawiki.org> | 2006-11-21 09:53:45 +0000 |
commit | 2f12a58d93a4783acb97956c945d0f28875e42c4 (patch) | |
tree | 574c2e839bb464977d6fa231445f9ee0fe54a70b | |
parent | 02efcccdbf20686fd8e27cf94bdc9b462417aa6e (diff) | |
download | mediawikicore-2f12a58d93a4783acb97956c945d0f28875e42c4.tar.gz mediawikicore-2f12a58d93a4783acb97956c945d0f28875e42c4.zip |
* Introduced StringUtils.php, populated it with some generic string functions, both new and collected from various other files.
* Removed some backtracking regexes with an O(N^2) worst case, replaced with StringUtils::delimiterReplace(). There is a beneficial functional difference: /*/ is no longer considered to be a complete CSS comment.
* Changed the parser strip state from an array to an object. This should hopefully avoid the PHP bugs with array references. StripState uses the new ReplacementArray to do the replacements, thereby supporting FSS.
* Removed DatabaseFunctions.php from the default startup sequence. Moved wfGetDB() to GlobalFunctions.php.
* Introduced the SiteStats class, with a collection of cached site stats accessor functions.
* Removed all global functions from Parser.php, they don't belong there.
* Made LanguageConverter use the new ReplacementArray class instead of managing its own FSS objects.
Notes
Notes:
http://mediawiki.org/wiki/Special:Code/MediaWiki/17820
-rw-r--r-- | includes/AutoLoader.php | 10 | ||||
-rw-r--r-- | includes/BagOStuff.php | 5 | ||||
-rw-r--r-- | includes/Block.php | 2 | ||||
-rw-r--r-- | includes/CoreParserFunctions.php | 16 | ||||
-rw-r--r-- | includes/Database.php | 4 | ||||
-rw-r--r-- | includes/DatabaseFunctions.php | 14 | ||||
-rw-r--r-- | includes/GlobalFunctions.php | 61 | ||||
-rw-r--r-- | includes/Image.php | 2 | ||||
-rw-r--r-- | includes/Linker.php | 2 | ||||
-rw-r--r-- | includes/MagicWord.php | 2 | ||||
-rw-r--r-- | includes/Parser.php | 371 | ||||
-rw-r--r-- | includes/Sanitizer.php | 5 | ||||
-rw-r--r-- | includes/SiteStats.php (renamed from includes/SiteStatsUpdate.php) | 80 | ||||
-rw-r--r-- | includes/SpecialStatistics.php | 39 | ||||
-rw-r--r-- | includes/SpecialWatchlist.php | 4 | ||||
-rw-r--r-- | includes/Xml.php | 14 | ||||
-rw-r--r-- | languages/LanguageConverter.php | 47 | ||||
-rw-r--r-- | languages/classes/LanguageKk.php | 11 | ||||
-rw-r--r-- | languages/classes/LanguageSr.php | 17 | ||||
-rw-r--r-- | languages/classes/LanguageZh.php | 17 | ||||
-rw-r--r-- | maintenance/namespace2sql.php | 4 |
21 files changed, 315 insertions, 412 deletions
diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 15fe3e79d13a..f826ec1c2cc1 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -86,7 +86,6 @@ function __autoload($className) { 'FileStore' => 'includes/FileStore.php', 'FSException' => 'includes/FileStore.php', 'FSTransaction' => 'includes/FileStore.php', - 'ReplacerCallback' => 'includes/GlobalFunctions.php', 'HTMLForm' => 'includes/HTMLForm.php', 'HistoryBlob' => 'includes/HistoryBlob.php', 'ConcatenatedGzipHistoryBlob' => 'includes/HistoryBlob.php', @@ -150,7 +149,8 @@ function __autoload($className) { 'SearchUpdate' => 'includes/SearchUpdate.php', 'SearchUpdateMyISAM' => 'includes/SearchUpdate.php', 'SiteConfiguration' => 'includes/SiteConfiguration.php', - 'SiteStatsUpdate' => 'includes/SiteStatsUpdate.php', + 'SiteStats' => 'includes/SiteStats.php', + 'SiteStatsUpdate' => 'includes/SiteStats.php', 'Skin' => 'includes/Skin.php', 'MediaWiki_I18N' => 'includes/SkinTemplate.php', 'SkinTemplate' => 'includes/SkinTemplate.php', @@ -215,6 +215,12 @@ function __autoload($className) { 'WantedPagesPage' => 'includes/SpecialWantedpages.php', 'WhatLinksHerePage' => 'includes/SpecialWhatlinkshere.php', 'SquidUpdate' => 'includes/SquidUpdate.php', + 'ReplacementArray' => 'includes/StringUtils.php', + 'Replacer' => 'includes/StringUtils.php', + 'RegexlikeReplacer' => 'includes/StringUtils.php', + 'DoubleReplacer' => 'includes/StringUtils.php', + 'HashtableReplacer' => 'includes/StringUtils.php', + 'StringUtils' => 'includes/StringUtils.php', 'Title' => 'includes/Title.php', 'User' => 'includes/User.php', 'MailAddress' => 'includes/UserMailer.php', diff --git a/includes/BagOStuff.php b/includes/BagOStuff.php index 1dc93a2fb0bd..75951268caa7 100644 --- a/includes/BagOStuff.php +++ b/includes/BagOStuff.php @@ -492,11 +492,14 @@ class TurckBagOStuff extends BagOStuff { class APCBagOStuff extends BagOStuff { function get($key) { $val = apc_fetch($key); + if ( is_string( $val ) ) { + $val = unserialize( $val ); + } return $val; } function set($key, $value, $exptime=0) { - apc_store($key, $value, $exptime); + apc_store($key, serialize($value), $exptime); return true; } diff --git a/includes/Block.php b/includes/Block.php index 39ebe04c8b8a..547bf53a12c1 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -338,7 +338,7 @@ class Block call_user_func( $callback, $block, $tag ); } } - wfFreeResult( $res ); + $db->freeResult( $res ); return $num_rows; } diff --git a/includes/CoreParserFunctions.php b/includes/CoreParserFunctions.php index b2ee789dd212..c0cdba95465e 100644 --- a/includes/CoreParserFunctions.php +++ b/includes/CoreParserFunctions.php @@ -126,21 +126,21 @@ class CoreParserFunctions { function statisticsFunction( $func, $raw = null ) { if ( self::isRaw( $raw ) ) { - return call_user_func( $func ); + return call_user_func( array( 'SiteStats', $func ) ); } else { global $wgContLang; - return $wgContLang->formatNum( call_user_func( $func ) ); + return $wgContLang->formatNum( call_user_func( array( 'SiteStats', $func ) ) ); } } - function numberofpages( $parser, $raw = null ) { return self::statisticsFunction( 'wfNumberOfPages', $raw ); } - function numberofusers( $parser, $raw = null ) { return self::statisticsFunction( 'wfNumberOfUsers', $raw ); } - function numberofarticles( $parser, $raw = null ) { return self::statisticsFunction( 'wfNumberOfArticles', $raw ); } - function numberoffiles( $parser, $raw = null ) { return self::statisticsFunction( 'wfNumberOfFiles', $raw ); } - function numberofadmins( $parser, $raw = null ) { return self::statisticsFunction( 'wfNumberOfAdmins', $raw ); } + function numberofpages( $parser, $raw = null ) { return self::statisticsFunction( 'pages', $raw ); } + function numberofusers( $parser, $raw = null ) { return self::statisticsFunction( 'users', $raw ); } + function numberofarticles( $parser, $raw = null ) { return self::statisticsFunction( 'articles', $raw ); } + function numberoffiles( $parser, $raw = null ) { return self::statisticsFunction( 'images', $raw ); } + function numberofadmins( $parser, $raw = null ) { return self::statisticsFunction( 'admins', $raw ); } function pagesinnamespace( $parser, $namespace = 0, $raw = null ) { - $count = wfPagesInNs( intval( $namespace ) ); + $count = SiteStats::pagesInNs( intval( $namespace ) ); if ( self::isRaw( $raw ) ) { global $wgContLang; return $wgContLang->formatNum( $count ); diff --git a/includes/Database.php b/includes/Database.php index 7b6df376e0b7..d8f7757f78fe 100644 --- a/includes/Database.php +++ b/includes/Database.php @@ -295,7 +295,7 @@ class Database { * Turns on (false) or off (true) the automatic generation and sending * of a "we're sorry, but there has been a database error" page on * database errors. Default is on (false). When turned off, the - * code should use wfLastErrno() and wfLastError() to handle the + * code should use lastErrno() and lastError() to handle the * situation as appropriate. */ function ignoreErrors( $ignoreErrors = NULL ) { @@ -1296,7 +1296,7 @@ class Database { } /** - * Makes a wfStrencoded list from an array + * Makes an encoded list of strings from an array * $mode: * LIST_COMMA - comma separated, no field names * LIST_AND - ANDed WHERE clause (without the WHERE) diff --git a/includes/DatabaseFunctions.php b/includes/DatabaseFunctions.php index 74b35a31bff4..c9dc9e7259aa 100644 --- a/includes/DatabaseFunctions.php +++ b/includes/DatabaseFunctions.php @@ -1,8 +1,7 @@ <?php /** - * Backwards compatibility wrapper for Database.php - * - * Note: $wgDatabase has ceased to exist. Destroy all references. + * Legacy database functions, for compatibility with pre-1.3 code + * NOTE: this file is no longer loaded by default. * * @package MediaWiki */ @@ -44,15 +43,6 @@ function wfSingleQuery( $sql, $dbi, $fname = '' ) { return $ret; } -/* - * @todo document function - */ -function &wfGetDB( $db = DB_LAST, $groups = array() ) { - global $wgLoadBalancer; - $ret =& $wgLoadBalancer->getConnection( $db, true, $groups ); - return $ret; -} - /** * Turns on (false) or off (true) the automatic generation and sending * of a "we're sorry, but there has been a database error" page on diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index d6ee0d784605..663273585f66 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -26,7 +26,6 @@ $wgTotalViews = -1; $wgTotalEdits = -1; -require_once( 'DatabaseFunctions.php' ); require_once( 'LogPage.php' ); require_once( 'normal/UtfNormalUtil.php' ); require_once( 'XmlFunctions.php' ); @@ -1736,16 +1735,10 @@ function wfUseMW( $req_ver ) { } /** - * Escape a string to make it suitable for inclusion in a preg_replace() - * replacement parameter. - * - * @param string $string - * @return string + * @deprecated use StringUtils::escapeRegexReplacement */ function wfRegexReplacement( $string ) { - $string = str_replace( '\\', '\\\\', $string ); - $string = str_replace( '$', '\\$', $string ); - return $string; + return StringUtils::escapeRegexReplacement( $string ); } /** @@ -1815,42 +1808,12 @@ function wfDoUpdates() } /** - * More or less "markup-safe" explode() - * Ignores any instances of the separator inside <...> - * @param string $separator - * @param string $text - * @return array + * @deprecated use StringUtils::explodeMarkup */ function wfExplodeMarkup( $separator, $text ) { - $placeholder = "\x00"; - - // Just in case... - $text = str_replace( $placeholder, '', $text ); - - // Trim stuff - $replacer = new ReplacerCallback( $separator, $placeholder ); - $cleaned = preg_replace_callback( '/(<.*?>)/', array( $replacer, 'go' ), $text ); - - $items = explode( $separator, $cleaned ); - foreach( $items as $i => $str ) { - $items[$i] = str_replace( $placeholder, $separator, $str ); - } - - return $items; + return StringUtils::explodeMarkup( $separator, $text ); } -class ReplacerCallback { - function ReplacerCallback( $from, $to ) { - $this->from = $from; - $this->to = $to; - } - - function go( $matches ) { - return str_replace( $this->from, $this->to, $matches[1] ); - } -} - - /** * Convert an arbitrarily-long digit string from one numeric base * to another, optionally zero-padding to a minimum column width. @@ -2074,4 +2037,20 @@ function wfWikiID() { } } +/* + * Get a Database object + * @param integer $db Index of the connection to get. May be DB_MASTER for the + * master (for write queries), DB_SLAVE for potentially lagged + * read queries, or an integer >= 0 for a particular server. + * + * @param array $groups Query groups. A list of group names that this query + * belongs to. + */ +function &wfGetDB( $db = DB_LAST, $groups = array() ) { + global $wgLoadBalancer; + $ret =& $wgLoadBalancer->getConnection( $db, true, $groups ); + return $ret; +} + + ?> diff --git a/includes/Image.php b/includes/Image.php index b2a63968aec7..c03466b2b7d2 100644 --- a/includes/Image.php +++ b/includes/Image.php @@ -1462,7 +1462,7 @@ class Image array( 'img_name' => $this->title->getDBkey() ), __METHOD__ ); - if ( 0 == wfNumRows( $this->historyRes ) ) { + if ( 0 == $dbr->numRows( $this->historyRes ) ) { return FALSE; } } else if ( $this->historyLine == 1 ) { diff --git a/includes/Linker.php b/includes/Linker.php index 2a50547d6194..f4e52ea50973 100644 --- a/includes/Linker.php +++ b/includes/Linker.php @@ -959,7 +959,7 @@ class Linker { $match[1] = substr($match[1], 1); $thelink = $this->makeLink( $match[1], $text, "", $trail ); } - $comment = preg_replace( $linkRegexp, wfRegexReplacement( $thelink ), $comment, 1 ); + $comment = preg_replace( $linkRegexp, StringUtils::escapeRegexReplacement( $thelink ), $comment, 1 ); } wfProfileOut( __METHOD__ ); return $comment; diff --git a/includes/MagicWord.php b/includes/MagicWord.php index 68cbe34531e7..350fb8ed169f 100644 --- a/includes/MagicWord.php +++ b/includes/MagicWord.php @@ -298,7 +298,7 @@ class MagicWord { * Replaces the word with something else */ function replace( $replacement, $subject, $limit=-1 ) { - $res = preg_replace( $this->getRegex(), wfRegexReplacement( $replacement ), $subject, $limit ); + $res = preg_replace( $this->getRegex(), StringUtils::escapeRegexReplacement( $replacement ), $subject, $limit ); $this->mModified = !($res === $subject); return $res; } diff --git a/includes/Parser.php b/includes/Parser.php index e5550dc125b1..73ac43ce5585 100644 --- a/includes/Parser.php +++ b/includes/Parser.php @@ -97,7 +97,7 @@ class Parser var $mTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables; # Cleared with clearState(): - var $mOutput, $mAutonumber, $mDTopen, $mStripState = array(); + var $mOutput, $mAutonumber, $mDTopen, $mStripState; var $mIncludeCount, $mArgStack, $mLastSection, $mInPre; var $mInterwikiLinkHolders, $mLinkHolders, $mUniqPrefix; var $mIncludeSizes; @@ -112,7 +112,9 @@ class Parser $mTitle, // Title context, used for self-link rendering and similar things $mOutputType, // Output type, one of the OT_xxx constants $ot, // Shortcut alias, see setOutputType() - $mRevisionId; // ID to display in {{REVISIONID}} tags + $mRevisionId, // ID to display in {{REVISIONID}} tags + $mRevisionTimestamp, // The timestamp of the specified revision ID + $mRevIdForTs; // The revision ID which was used to fetch the timestamp /**#@-*/ @@ -174,7 +176,6 @@ class Parser } $this->initialiseVariables(); - $this->mFirstCall = false; wfProfileOut( __METHOD__ ); } @@ -194,7 +195,7 @@ class Parser $this->mLastSection = ''; $this->mDTopen = false; $this->mIncludeCount = array(); - $this->mStripState = array(); + $this->mStripState = new StripState; $this->mArgStack = array(); $this->mInPre = false; $this->mInterwikiLinkHolders = array( @@ -208,8 +209,8 @@ class Parser 'texts' => array(), 'titles' => array() ); - $this->mRevisionId = null; - + $this->mRevisionTimestamp = $this->mRevisionId = null; + /** * Prefix for temporary replacement strings for the multipass parser. * \x07 should never appear in input as it's disallowed in XML. @@ -286,22 +287,17 @@ class Parser $this->mOptions = $options; $this->mTitle =& $title; $oldRevisionId = $this->mRevisionId; + $oldRevisionTimestamp = $this->mRevisionTimestamp; if( $revid !== null ) { $this->mRevisionId = $revid; + $this->mRevisionTimestamp = null; } $this->setOutputType( OT_HTML ); - - //$text = $this->strip( $text, $this->mStripState ); - // VOODOO MAGIC FIX! Sometimes the above segfaults in PHP5. - $x =& $this->mStripState; - - wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$x ) ); - $text = $this->strip( $text, $x ); - wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$x ) ); - + wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) ); + $text = $this->strip( $text, $this->mStripState ); + wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) ); $text = $this->internalParse( $text ); - - $text = $this->unstrip( $text, $this->mStripState ); + $text = $this->mStripState->unstripGeneral( $text ); # Clean up special characters, only run once, next-to-last before doBlockLevels $fixtags = array( @@ -324,7 +320,7 @@ class Parser # Side-effects: this calls $this->mOutput->setTitleText() $text = $wgContLang->parserConvert( $text, $this ); - $text = $this->unstripNoWiki( $text, $this->mStripState ); + $text = $this->mStripState->unstripNoWiki( $text ); wfRunHooks( 'ParserBeforeTidy', array( &$this, &$text ) ); @@ -374,6 +370,7 @@ class Parser } $this->mOutput->setText( $text ); $this->mRevisionId = $oldRevisionId; + $this->mRevisionTimestamp = $oldRevisionTimestamp; wfProfileOut( $fname ); wfProfileOut( __METHOD__ ); @@ -405,16 +402,14 @@ class Parser $this->setOutputType( OT_PREPROCESS ); $this->mOptions = $options; $this->mTitle = $title; - $x =& $this->mStripState; - wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$x ) ); - $text = $this->strip( $text, $x ); - wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$x ) ); + wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) ); + $text = $this->strip( $text, $this->mStripState ); + wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) ); if ( $this->mOptions->getRemoveComments() ) { $text = Sanitizer::removeHTMLcomments( $text ); } $text = $this->replaceVariables( $text ); - $text = $this->unstrip( $text, $x ); - $text = $this->unstripNowiki( $text, $x ); + $text = $this->mStripState->unstripBoth( $text ); wfProfileOut( __METHOD__ ); return $text; } @@ -521,7 +516,8 @@ class Parser * Strips and renders nowiki, pre, math, hiero * If $render is set, performs necessary rendering operations on plugins * Returns the text, and fills an array with data needed in unstrip() - * If the $state is already a valid strip state, it adds to the state + * + * @param StripState $state * * @param bool $stripcomments when set, HTML comments <!-- like this --> * will be stripped in addition to other tags. This is important @@ -533,12 +529,12 @@ class Parser * * @private */ - function strip( $text, &$state, $stripcomments = false , $dontstrip = array () ) { + function strip( $text, $state, $stripcomments = false , $dontstrip = array () ) { wfProfileIn( __METHOD__ ); $render = ($this->mOutputType == OT_HTML); $uniq_prefix = $this->mUniqPrefix; - $commentState = array(); + $commentState = new ReplacementArray; $elements = array_merge( array( 'nowiki', 'gallery' ), @@ -583,7 +579,7 @@ class Parser } // Shouldn't happen otherwise. :) case 'nowiki': - $output = wfEscapeHTMLTagsOnly( $content ); + $output = Xml::escapeTagsOnly( $content ); break; case 'math': $output = MathRenderer::renderMath( $content ); @@ -607,14 +603,14 @@ class Parser // Unstrip the output, because unstrip() is no longer recursive so // it won't do it itself - $output = $this->unstrip( $output, $state ); + $output = $state->unstripBoth( $output ); if( !$stripcomments && $element == '!--' ) { - $commentState[$marker] = $output; + $commentState->setPair( $marker, $output ); } elseif ( $element == 'html' || $element == 'nowiki' ) { - $state['nowiki'][$marker] = $output; + $state->nowiki->setPair( $marker, $output ); } else { - $state['general'][$marker] = $output; + $state->general->setPair( $marker, $output ); } } @@ -624,7 +620,7 @@ class Parser # a comment.) if ( !$stripcomments ) { // Put them all back and forget them - $text = strtr( $text, $commentState ); + $text = $commentState->replace( $text ); } wfProfileOut( __METHOD__ ); @@ -636,35 +632,27 @@ class Parser * * always call unstripNoWiki() after this one * @private + * @deprecated use $this->mStripState->unstrip() */ function unstrip( $text, $state ) { - if ( !isset( $state['general'] ) ) { - return $text; - } - - wfProfileIn( __METHOD__ ); - # TODO: good candidate for FSS - $text = strtr( $text, $state['general'] ); - wfProfileOut( __METHOD__ ); - return $text; + return $state->unstripGeneral( $text ); } /** * Always call this after unstrip() to preserve the order * * @private + * @deprecated use $this->mStripState->unstrip() */ function unstripNoWiki( $text, $state ) { - if ( !isset( $state['nowiki'] ) ) { - return $text; - } - - wfProfileIn( __METHOD__ ); - # TODO: good candidate for FSS - $text = strtr( $text, $state['nowiki'] ); - wfProfileOut( __METHOD__ ); + return $state->unstripNoWiki( $text ); + } - return $text; + /** + * @deprecated use $this->mStripState->unstripBoth() + */ + function unstripForHTML( $text ) { + return $this->mStripState->unstripBoth( $text ); } /** @@ -676,10 +664,7 @@ class Parser */ function insertStripItem( $text, &$state ) { $rnd = $this->mUniqPrefix . '-item' . Parser::getRandomString(); - if ( !$state ) { - $state = array(); - } - $state['general'][$rnd] = $text; + $state->general->setPair( $rnd, $text ); return $rnd; } @@ -815,7 +800,7 @@ class Parser if ( preg_match( '/^(:*)\{\|(.*)$/', $x, $matches ) ) { $indent_level = strlen( $matches[1] ); - $attributes = $this->unstripForHTML( $matches[2] ); + $attributes = $this->mStripState->unstripBoth( $matches[2] ); $t[$k] = str_repeat( '<dl><dd>', $indent_level ) . '<table' . Sanitizer::fixTagAttributes ( $attributes, 'table' ) . '>' ; @@ -849,7 +834,7 @@ class Parser array_push ( $tr , false ) ; array_push ( $td , false ) ; array_push ( $ltd , '' ) ; - $attributes = $this->unstripForHTML( $x ); + $attributes = $this->mStripState->unstripBoth( $x ); array_push ( $ltr , Sanitizer::fixTagAttributes ( $attributes, 'tr' ) ) ; } else if ( '|' == $fc || '!' == $fc || '|+' == substr ( $x , 0 , 2 ) ) { # Caption @@ -865,7 +850,7 @@ class Parser // FIXME: This can result in improper nesting of tags processed // by earlier parser steps, but should avoid splitting up eg // attribute values containing literal "||". - $after = wfExplodeMarkup( '||', $after ); + $after = StringUtils::explodeMarkup( '||', $after ); $t[$k] = '' ; @@ -906,7 +891,7 @@ class Parser if ( count ( $y ) == 1 ) $y = "{$z}<{$l}>{$y[0]}" ; else { - $attributes = $this->unstripForHTML( $y[0] ); + $attributes = $this->mStripState->unstripBoth( $y[0] ); $y = "{$z}<{$l}".Sanitizer::fixTagAttributes($attributes, $l).">{$y[1]}" ; } $t[$k] .= $y ; @@ -955,7 +940,7 @@ class Parser # Remove <noinclude> tags and <includeonly> sections $text = strtr( $text, array( '<onlyinclude>' => '' , '</onlyinclude>' => '' ) ); $text = strtr( $text, array( '<noinclude>' => '', '</noinclude>' => '') ); - $text = preg_replace( '/<includeonly>.*?<\/includeonly>/s', '', $text ); + $text = StringUtils::delimiterReplace( '<includeonly>', '</includeonly>', '', $text ); $text = Sanitizer::removeHTMLtags( $text, array( &$this, 'attributeStripCallback' ) ); @@ -1611,7 +1596,7 @@ class Parser wfProfileOut( "$fname-misc" ); wfProfileIn( "$fname-title" ); - $nt = Title::newFromText( $this->unstripNoWiki($link, $this->mStripState) ); + $nt = Title::newFromText( $this->mStripState->unstripNoWiki($link) ); if( !$nt ) { $s .= $prefix . '[[' . $line; wfProfileOut( "$fname-title" ); @@ -2434,15 +2419,15 @@ class Parser case 'revisionid': return $this->mRevisionId; case 'revisionday': - return intval( substr( wfRevisionTimestamp( $this->mRevisionId ), 6, 2 ) ); + return intval( substr( $this->getRevisionTimestamp(), 6, 2 ) ); case 'revisionday2': - return substr( wfRevisionTimestamp( $this->mRevisionId ), 6, 2 ); + return substr( $this->getRevisionTimestamp(), 6, 2 ); case 'revisionmonth': - return intval( substr( wfRevisionTimestamp( $this->mRevisionId ), 4, 2 ) ); + return intval( substr( $this->getRevisionTimestamp(), 4, 2 ) ); case 'revisionyear': - return substr( wfRevisionTimestamp( $this->mRevisionId ), 0, 4 ); + return substr( $this->getRevisionTimestamp(), 0, 4 ); case 'revisiontimestamp': - return wfRevisionTimestamp( $this->mRevisionId ); + return $this->getRevisionTimestamp(); case 'namespace': return str_replace('_',' ',$wgContLang->getNsText( $this->mTitle->getNamespace() ) ); case 'namespacee': @@ -2484,15 +2469,15 @@ class Parser case 'localdow': return $varCache[$index] = $wgContLang->formatNum( $localDayOfWeek ); case 'numberofarticles': - return $varCache[$index] = $wgContLang->formatNum( wfNumberOfArticles() ); + return $varCache[$index] = $wgContLang->formatNum( SiteStats::articles() ); case 'numberoffiles': - return $varCache[$index] = $wgContLang->formatNum( wfNumberOfFiles() ); + return $varCache[$index] = $wgContLang->formatNum( SiteStats::images() ); case 'numberofusers': - return $varCache[$index] = $wgContLang->formatNum( wfNumberOfUsers() ); + return $varCache[$index] = $wgContLang->formatNum( SiteStats::users() ); case 'numberofpages': - return $varCache[$index] = $wgContLang->formatNum( wfNumberOfPages() ); + return $varCache[$index] = $wgContLang->formatNum( SiteStats::pages() ); case 'numberofadmins': - return $varCache[$index] = $wgContLang->formatNum( wfNumberOfAdmins() ); + return $varCache[$index] = $wgContLang->formatNum( SiteStats::admins() ); case 'currenttimestamp': return $varCache[$index] = wfTimestampNow(); case 'localtimestamp': @@ -3079,14 +3064,13 @@ class Parser if ( !$noparse ) { # If there are any <onlyinclude> tags, only include them if ( in_string( '<onlyinclude>', $text ) && in_string( '</onlyinclude>', $text ) ) { - $m = array(); - preg_match_all( '/<onlyinclude>(.*?)\n?<\/onlyinclude>/s', $text, $m ); - $text = ''; - foreach ($m[1] as $piece) - $text .= $piece; + $replacer = new OnlyIncludeReplacer; + StringUtils::delimiterReplaceCallback( '<onlyinclude>', '</onlyinclude>', + array( &$replacer, 'replace' ), $text ); + $text = $replacer->output; } # Remove <noinclude> sections and <includeonly> tags - $text = preg_replace( '/<noinclude>.*?<\/noinclude>/s', '', $text ); + $text = StringUtils::delimiterReplace( '<noinclude>', '</noinclude>', '', $text ); $text = strtr( $text, array( '<includeonly>' => '' , '</includeonly>' => '' ) ); if( $this->ot['html'] || $this->ot['pre'] ) { @@ -3481,8 +3465,7 @@ class Parser # The canonized header is a version of the header text safe to use for links # Avoid insertion of weird stuff like <math> by expanding the relevant sections - $canonized_headline = $this->unstrip( $headline, $this->mStripState ); - $canonized_headline = $this->unstripNoWiki( $canonized_headline, $this->mStripState ); + $canonized_headline = $this->mStripState->unstripBoth( $headline ); # Remove link placeholders by the link text. # <!--LINK number--> @@ -3604,15 +3587,14 @@ class Parser $this->clearState(); } - $stripState = false; + $stripState = new StripState; $pairs = array( "\r\n" => "\n", ); $text = str_replace( array_keys( $pairs ), array_values( $pairs ), $text ); $text = $this->strip( $text, $stripState, true, array( 'gallery' ) ); $text = $this->pstPass2( $text, $stripState, $user ); - $text = $this->unstrip( $text, $stripState ); - $text = $this->unstripNoWiki( $text, $stripState ); + $text = $stripState->unstripBoth( $text ); return $text; } @@ -3915,7 +3897,6 @@ class Parser */ function replaceLinkHolders( &$text, $options = 0 ) { global $wgUser; - global $wgOutputReplace; global $wgContLang; $fname = 'Parser::replaceLinkHolders'; @@ -4095,7 +4076,7 @@ class Parser # Construct search and replace arrays wfProfileIn( $fname.'-construct' ); - $wgOutputReplace = array(); + $replacePairs = array(); foreach ( $this->mLinkHolders['namespaces'] as $key => $ns ) { $pdbk = $pdbks[$key]; $searchkey = "<!--LINK $key-->"; @@ -4104,27 +4085,27 @@ class Parser $linkCache->addBadLinkObj( $title ); $colours[$pdbk] = 0; $this->mOutput->addLink( $title, 0 ); - $wgOutputReplace[$searchkey] = $sk->makeBrokenLinkObj( $title, + $replacePairs[$searchkey] = $sk->makeBrokenLinkObj( $title, $this->mLinkHolders['texts'][$key], $this->mLinkHolders['queries'][$key] ); } elseif ( $colours[$pdbk] == 1 ) { - $wgOutputReplace[$searchkey] = $sk->makeKnownLinkObj( $title, + $replacePairs[$searchkey] = $sk->makeKnownLinkObj( $title, $this->mLinkHolders['texts'][$key], $this->mLinkHolders['queries'][$key] ); } elseif ( $colours[$pdbk] == 2 ) { - $wgOutputReplace[$searchkey] = $sk->makeStubLinkObj( $title, + $replacePairs[$searchkey] = $sk->makeStubLinkObj( $title, $this->mLinkHolders['texts'][$key], $this->mLinkHolders['queries'][$key] ); } } + $replacer = new HashtableReplacer( $replacePairs, 1 ); wfProfileOut( $fname.'-construct' ); # Do the thing wfProfileIn( $fname.'-replace' ); - $text = preg_replace_callback( '/(<!--LINK .*?-->)/', - "wfOutputReplaceMatches", + $replacer->cb(), $text); wfProfileOut( $fname.'-replace' ); @@ -4135,15 +4116,16 @@ class Parser if ( !empty( $this->mInterwikiLinkHolders['texts'] ) ) { wfProfileIn( $fname.'-interwiki' ); # Make interwiki link HTML - $wgOutputReplace = array(); + $replacePairs = array(); foreach( $this->mInterwikiLinkHolders['texts'] as $key => $link ) { $title = $this->mInterwikiLinkHolders['titles'][$key]; - $wgOutputReplace[$key] = $sk->makeLinkObj( $title, $link ); + $replacePairs[$key] = $sk->makeLinkObj( $title, $link ); } + $replacer = new HashtableReplacer( $replacePairs, 1 ); $text = preg_replace_callback( '/<!--IWLINK (.*?)-->/', - "wfOutputReplaceMatches", + $replacer->cb(), $text ); wfProfileOut( $fname.'-interwiki' ); } @@ -4196,11 +4178,11 @@ class Parser */ function renderPreTag( $text, $attribs ) { // Backwards-compatibility hack - $content = preg_replace( '!<nowiki>(.*?)</nowiki>!is', '\\1', $text ); + $content = StringUtils::delimiterReplace( '<nowiki>', '</nowiki>', '$1', $text, 'i' ); $attribs = Sanitizer::validateTagAttributes( $attribs, 'pre' ); return wfOpenElement( 'pre', $attribs ) . - wfEscapeHTMLTagsOnly( $content ) . + Xml::escapeTagsOnly( $content ) . '</pre>'; } @@ -4343,7 +4325,7 @@ class Parser # make sure there are no placeholders in thumbnail attributes # that are later expanded to html- so expand them now and # remove the tags - $alt = $this->unstrip($alt, $this->mStripState); + $alt = $this->mStripState->unstripBoth( $alt ); $alt = Sanitizer::stripAllTags( $alt ); # Linker does the rest @@ -4370,15 +4352,10 @@ class Parser */ function attributeStripCallback( &$text, $args ) { $text = $this->replaceVariables( $text, $args ); - $text = $this->unstripForHTML( $text ); + $text = $this->mStripState->unstripBoth( $text ); return $text; } - function unstripForHTML( $text ) { - $text = $this->unstrip( $text, $this->mStripState ); - $text = $this->unstripNoWiki( $text, $this->mStripState ); - return $text; - } /**#@-*/ /**#@+ @@ -4414,14 +4391,14 @@ class Parser private function extractSections( $text, $section, $mode, $newtext='' ) { # strip NOWIKI etc. to avoid confusion (true-parameter causes HTML # comments to be stripped as well) - $striparray = array(); + $stripState = new StripState; $oldOutputType = $this->mOutputType; $oldOptions = $this->mOptions; $this->mOptions = new ParserOptions(); $this->setOutputType( OT_WIKI ); - $striptext = $this->strip( $text, $striparray, true ); + $striptext = $this->strip( $text, $stripState, true ); $this->setOutputType( $oldOutputType ); $this->mOptions = $oldOptions; @@ -4528,9 +4505,7 @@ class Parser } } # reinsert stripped tags - $rv = $this->unstrip( $rv, $striparray ); - $rv = $this->unstripNoWiki( $rv, $striparray ); - $rv = trim( $rv ); + $rv = trim( $stripState->unstripBoth( $rv ) ); return $rv; } @@ -4553,6 +4528,23 @@ class Parser return $this->extractSections( $oldtext, $section, "replace", $text ); } + /** + * Get the timestamp associated with the current revision, adjusted for + * the user's current timestamp + */ + function getRevisionTimestamp() { + if ( is_null( $this->mRevisionTimestamp ) ) { + wfProfileIn( __METHOD__ ); + global $wgContLang; + $dbr =& wfGetDB( DB_SLAVE ); + $timestamp = $dbr->selectField( 'revision', 'rev_timestamp', + array( 'rev_id' => $id ), __METHOD__ ); + $this->mRevisionTimestamp = $wgContLang->userAdjust( $timestamp ); + + wfProfileOut( __METHOD__ ); + } + return $this->mRevisionTimestamp; + } } /** @@ -4787,152 +4779,47 @@ class ParserOptions } } -/** - * Callback function used by Parser::replaceLinkHolders() - * to substitute link placeholders. - */ -function &wfOutputReplaceMatches( $matches ) { - global $wgOutputReplace; - return $wgOutputReplace[$matches[1]]; -} +class OnlyIncludeReplacer { + var $output = ''; -/** - * Return the total number of articles - */ -function wfNumberOfArticles() { - global $wgNumberOfArticles; - - wfLoadSiteStats(); - return $wgNumberOfArticles; -} - -/** - * Return the number of files - */ -function wfNumberOfFiles() { - $fname = 'wfNumberOfFiles'; - - wfProfileIn( $fname ); - $dbr =& wfGetDB( DB_SLAVE ); - $numImages = $dbr->selectField('site_stats', 'ss_images', array(), $fname ); - wfProfileOut( $fname ); - - return $numImages; -} - -/** - * Return the number of user accounts - * @return integer - */ -function wfNumberOfUsers() { - wfProfileIn( 'wfNumberOfUsers' ); - $dbr =& wfGetDB( DB_SLAVE ); - $count = $dbr->selectField( 'site_stats', 'ss_users', array(), 'wfNumberOfUsers' ); - wfProfileOut( 'wfNumberOfUsers' ); - return (int)$count; + function replace( $matches ) { + if ( substr( $matches[1], -1 ) == "\n" ) { + $this->output .= substr( $matches[1], 0, -1 ); + } else { + $this->output .= $matches[1]; + } + } } -/** - * Return the total number of pages - * @return integer - */ -function wfNumberOfPages() { - wfProfileIn( 'wfNumberOfPages' ); - $dbr =& wfGetDB( DB_SLAVE ); - $count = $dbr->selectField( 'site_stats', 'ss_total_pages', array(), 'wfNumberOfPages' ); - wfProfileOut( 'wfNumberOfPages' ); - return (int)$count; -} +class StripState { + var $general, $nowiki; -/** - * Return the total number of admins - * - * @return integer - */ -function wfNumberOfAdmins() { - static $admins = -1; - wfProfileIn( 'wfNumberOfAdmins' ); - if( $admins == -1 ) { - $dbr =& wfGetDB( DB_SLAVE ); - $admins = $dbr->selectField( 'user_groups', 'COUNT(*)', array( 'ug_group' => 'sysop' ), 'wfNumberOfAdmins' ); + function __construct() { + $this->general = new ReplacementArray; + $this->nowiki = new ReplacementArray; } - wfProfileOut( 'wfNumberOfAdmins' ); - return (int)$admins; -} -/** - * Count the number of pages in a particular namespace - * - * @param $ns Namespace - * @return integer - */ -function wfPagesInNs( $ns ) { - static $pageCount = array(); - wfProfileIn( 'wfPagesInNs' ); - if( !isset( $pageCount[$ns] ) ) { - $dbr =& wfGetDB( DB_SLAVE ); - $pageCount[$ns] = $dbr->selectField( 'page', 'COUNT(*)', array( 'page_namespace' => $ns ), 'wfPagesInNs' ); + function unstripGeneral( $text ) { + wfProfileIn( __METHOD__ ); + $text = $this->general->replace( $text ); + wfProfileOut( __METHOD__ ); + return $text; } - wfProfileOut( 'wfPagesInNs' ); - return (int)$pageCount[$ns]; -} -/** - * Get various statistics from the database - * @private - */ -function wfLoadSiteStats() { - global $wgNumberOfArticles, $wgTotalViews, $wgTotalEdits; - $fname = 'wfLoadSiteStats'; - - if ( -1 != $wgNumberOfArticles ) return; - $dbr =& wfGetDB( DB_SLAVE ); - $s = $dbr->selectRow( 'site_stats', - array( 'ss_total_views', 'ss_total_edits', 'ss_good_articles' ), - array( 'ss_row_id' => 1 ), $fname - ); - - if ( $s === false ) { - return; - } else { - $wgTotalViews = $s->ss_total_views; - $wgTotalEdits = $s->ss_total_edits; - $wgNumberOfArticles = $s->ss_good_articles; + function unstripNoWiki( $text ) { + wfProfileIn( __METHOD__ ); + $text = $this->nowiki->replace( $text ); + wfProfileOut( __METHOD__ ); + return $text; } -} -/** - * Get revision timestamp from the database considering timecorrection - * - * @param $id Int: page revision id - * @return integer - */ -function wfRevisionTimestamp( $id ) { - global $wgContLang; - $fname = 'wfRevisionTimestamp'; - - wfProfileIn( $fname ); - $dbr =& wfGetDB( DB_SLAVE ); - $timestamp = $dbr->selectField( 'revision', 'rev_timestamp', - array( 'rev_id' => $id ), __METHOD__ ); - $timestamp = $wgContLang->userAdjust( $timestamp ); - wfProfileOut( $fname ); - - return $timestamp; -} - -/** - * Escape html tags - * Basically replacing " > and < with HTML entities ( ", >, <) - * - * @param $in String: text that might contain HTML tags. - * @return string Escaped string - */ -function wfEscapeHTMLTagsOnly( $in ) { - return str_replace( - array( '"', '>', '<' ), - array( '"', '>', '<' ), - $in ); + function unstripBoth( $text ) { + wfProfileIn( __METHOD__ ); + $text = $this->general->replace( $text ); + $text = $this->nowiki->replace( $text ); + wfProfileOut( __METHOD__ ); + return $text; + } } ?> diff --git a/includes/Sanitizer.php b/includes/Sanitizer.php index 7d9ccc0fb727..4ed26923010c 100644 --- a/includes/Sanitizer.php +++ b/includes/Sanitizer.php @@ -603,7 +603,8 @@ class Sanitizer { $stripped = Sanitizer::decodeCharReferences( $value ); // Remove any comments; IE gets token splitting wrong - $stripped = preg_replace( '!/\\*.*?\\*/!S', ' ', $stripped ); + $stripped = StringUtils::delimiterReplace( '/\*', '\*/', ' ', $stripped ); + $value = $stripped; // ... and continue checks @@ -1178,7 +1179,7 @@ class Sanitizer { */ static function stripAllTags( $text ) { # Actual <tags> - $text = preg_replace( '/ < .*? > /x', '', $text ); + $text = StringUtils::delimiterReplace( '<', '>', '', $text ); # Normalize &entities and whitespace $text = Sanitizer::normalizeAttributeValue( $text ); diff --git a/includes/SiteStatsUpdate.php b/includes/SiteStats.php index b91dcfeb544b..4480ab597606 100644 --- a/includes/SiteStatsUpdate.php +++ b/includes/SiteStats.php @@ -1,9 +1,85 @@ <?php + /** - * See deferred.txt - * + * Static accessor class for site_stats and related things * @package MediaWiki */ +class SiteStats { + static $row, $loaded = false; + static $admins; + static $pageCount = array(); + + static function recache() { + self::load( true ); + } + + static function load( $recache = false ) { + if ( self::$loaded && !$recache ) { + return; + } + + $dbr =& wfGetDB( DB_SLAVE ); + self::$row = $dbr->selectRow( 'site_stats', '*', false, __METHOD__ ); + + # This code is somewhat schema-agnostic, because I'm changing it in a minor release -- TS + if ( !isset( self::$row->ss_total_pages ) && self::$row->ss_total_pages == -1 ) { + # Update schema + $u = new SiteStatsUpdate( 0, 0, 0 ); + $u->doUpdate(); + self::$row = $dbr->selectRow( 'site_stats', '*', false, $fname ); + } + } + + static function views() { + self::load(); + return self::$row->ss_total_views; + } + + static function edits() { + self::load(); + return self::$row->ss_total_edits; + } + + static function articles() { + self::load(); + return self::$row->ss_good_articles; + } + + static function pages() { + self::load(); + return self::$row->ss_total_pages; + } + + static function users() { + self::load(); + return self::$row->ss_users; + } + + static function images() { + self::load(); + return self::$row->ss_images; + } + + static function admins() { + if ( !isset( self::$admins ) ) { + $dbr =& wfGetDB( DB_SLAVE ); + self::$admins = $dbr->selectField( 'user_groups', 'COUNT(*)', array( 'ug_group' => 'sysop' ), __METHOD__ ); + } + return self::$admins; + } + + static function pagesInNs( $ns ) { + wfProfileIn( __METHOD__ ); + if( !isset( self::$pageCount[$ns] ) ) { + $dbr =& wfGetDB( DB_SLAVE ); + $pageCount[$ns] = (int)$dbr->selectField( 'page', 'COUNT(*)', array( 'page_namespace' => $ns ), __METHOD__ ); + } + wfProfileOut( __METHOD__ ); + return $pageCount[$ns]; + } + +} + /** * diff --git a/includes/SpecialStatistics.php b/includes/SpecialStatistics.php index 4a51efd9b5c2..66b1424039f4 100644 --- a/includes/SpecialStatistics.php +++ b/includes/SpecialStatistics.php @@ -15,39 +15,14 @@ function wfSpecialStatistics() { $action = $wgRequest->getVal( 'action' ); $dbr =& wfGetDB( DB_SLAVE ); - extract( $dbr->tableNames( 'page', 'site_stats', 'user', 'user_groups' ) ); + extract( $dbr->tableNames( 'site_stats', 'user', 'user_groups' ) ); - $row = $dbr->selectRow( 'site_stats', '*', false, $fname ); - $views = $row->ss_total_views; - $edits = $row->ss_total_edits; - $good = $row->ss_good_articles; - $images = $row->ss_images; - - # This code is somewhat schema-agnostic, because I'm changing it in a minor release -- TS - if ( isset( $row->ss_total_pages ) && $row->ss_total_pages == -1 ) { - # Update schema - $u = new SiteStatsUpdate( 0, 0, 0 ); - $u->doUpdate(); - $row = $dbr->selectRow( 'site_stats', '*', false, $fname ); - } - - if ( isset( $row->ss_total_pages ) ) { - $total = $row->ss_total_pages; - } else { - $sql = "SELECT COUNT(page_namespace) AS total FROM $page"; - $res = $dbr->query( $sql, $fname ); - $pageRow = $dbr->fetchObject( $res ); - $total = $pageRow->total; - } - - if ( isset( $row->ss_users ) ) { - $users = $row->ss_users; - } else { - $sql = "SELECT MAX(user_id) AS total FROM $user"; - $res = $dbr->query( $sql, $fname ); - $userRow = $dbr->fetchObject( $res ); - $users = $userRow->total; - } + $views = SiteStats::views(); + $edits = SiteStats::edits(); + $good = SiteStats::articles(); + $images = SiteStats::images(); + $total = SiteStats::pages(); + $users = SiteStats::users(); $admins = $dbr->selectField( 'user_groups', 'COUNT(*)', array( 'ug_group' => 'sysop' ), $fname ); $numJobs = $dbr->selectField( 'job', 'COUNT(*)', '', $fname ); diff --git a/includes/SpecialWatchlist.php b/includes/SpecialWatchlist.php index 0ce03b8b171d..bc170b36348c 100644 --- a/includes/SpecialWatchlist.php +++ b/includes/SpecialWatchlist.php @@ -381,8 +381,8 @@ function wfSpecialWatchlist( $par ) { } if ($wgRCShowWatchingUsers && $wgUser->getOption( 'shownumberswatching' )) { - $sql3 = "SELECT COUNT(*) AS n FROM $watchlist WHERE wl_title='" .wfStrencode($obj->page_title). "' AND wl_namespace='{$obj->page_namespace}'" ; - $res3 = $dbr->query( $sql3, DB_READ, $fname ); + $sql3 = "SELECT COUNT(*) AS n FROM $watchlist WHERE wl_title='" .$dbr->strencode($obj->page_title). "' AND wl_namespace='{$obj->page_namespace}'" ; + $res3 = $dbr->query( $sql3, $fname ); $x = $dbr->fetchObject( $res3 ); $rc->numberofWatchingusers = $x->n; } else { diff --git a/includes/Xml.php b/includes/Xml.php index 3457445860bb..6e66fc416f56 100644 --- a/includes/Xml.php +++ b/includes/Xml.php @@ -297,5 +297,19 @@ class Xml { '</html>'; return Xml::isWellFormed( $html ); } + + /** + * Escape html tags + * Basically replacing " > and < with HTML entities ( ", >, <) + * + * @param $in String: text that might contain HTML tags. + * @return string Escaped string + */ + function escapeTagsOnly( $in ) { + return str_replace( + array( '"', '>', '<' ), + array( '"', '>', '<' ), + $in ); + } } ?> diff --git a/languages/LanguageConverter.php b/languages/LanguageConverter.php index a0f7ee1d9a1c..86e025c58351 100644 --- a/languages/LanguageConverter.php +++ b/languages/LanguageConverter.php @@ -12,9 +12,7 @@ class LanguageConverter { var $mMainLanguageCode; var $mVariants, $mVariantFallbacks; var $mTablesLoaded = false; - var $mUseFss = false; var $mTables; - var $mFssObjects; var $mTitleDisplay=''; var $mDoTitleConvert=true, $mDoContentConvert=true; var $mCacheKey; @@ -49,9 +47,6 @@ class LanguageConverter { $this->mMarkup = array_merge($m, $markup); $f = array('A'=>'A', 'T'=>'T'); $this->mFlags = array_merge($f, $flags); - if ( function_exists( 'fss_prep_replace' ) ) { - $this->mUseFss = true; - } } /** @@ -194,19 +189,12 @@ class LanguageConverter { * @return string Translated text */ function translate( $text, $variant ) { + wfProfileIn( __METHOD__ ); if( !$this->mTablesLoaded ) $this->loadTables(); - if ( $this->mUseFss ) { - wfProfileIn( __METHOD__.'-fss' ); - $text = fss_exec_replace( $this->mFssObjects[$variant], $text ); - wfProfileOut( __METHOD__.'-fss' ); - return $text; - } else { - wfProfileIn( __METHOD__.'-strtr' ); - $text = strtr( $text, $this->mTables[$variant] ); - wfProfileOut( __METHOD__.'-strtr' ); - return $text; - } + $text = $this->mTables[$variant]->replace( $text ); + wfProfileOut( __METHOD__ ); + return $text; } /** @@ -407,13 +395,9 @@ class LanguageConverter { continue; if(!array_key_exists($vto, $carray)) continue; - $this->mTables[$vto][$carray[$vfrom]] = $carray[$vto]; - + $this->mTables[$vto]->setPair($carray[$vfrom], $carray[$vto]); } } - if ( $this->mUseFss ) { - $this->generateFssObjects(); - } } } else { @@ -557,8 +541,8 @@ class LanguageConverter { $this->mTables = $wgMemc->get( $this->mCacheKey ); wfProfileOut( __METHOD__.'-cache' ); } - if ( !$this->mTables ) { - wfProfileOut( __METHOD__.'-recache' ); + if ( !$this->mTables || !isset( $this->mTables['VERSION 2'] ) ) { + wfProfileIn( __METHOD__.'-recache' ); // not in cache, or we need a fresh reload. // we will first load the default tables // then update them using things in MediaWiki:Zhconversiontable/* @@ -566,10 +550,11 @@ class LanguageConverter { $this->loadDefaultTables(); foreach($this->mVariants as $var) { $cached = $this->parseCachedTable($var); - $this->mTables[$var] = array_merge($this->mTables[$var], $cached); + $this->mTables[$var]->mergeArray($cached); } $this->postLoadTables(); + $this->mTables['VERSION 2'] = true; if($this->lockCache()) { $wgMemc->set($this->mCacheKey, $this->mTables, 43200); @@ -577,23 +562,9 @@ class LanguageConverter { } wfProfileOut( __METHOD__.'-recache' ); } - if ( $this->mUseFss ) { - wfProfileIn( __METHOD__.'-fss' ); - $this->generateFssObjects(); - wfProfileOut( __METHOD__.'-fss' ); - } wfProfileOut( __METHOD__ ); } - /** - * Generate FSS objects. The FSS extension must be available. - */ - function generateFssObjects() { - foreach ( $this->mTables as $variant => $table ) { - $this->mFssObjects[$variant] = fss_prep_replace( $table ); - } - } - /** * Hook for post processig after conversion tables are loaded * diff --git a/languages/classes/LanguageKk.php b/languages/classes/LanguageKk.php index bfbdc54702f0..71ca081df4f9 100644 --- a/languages/classes/LanguageKk.php +++ b/languages/classes/LanguageKk.php @@ -89,11 +89,12 @@ class KkConverter extends LanguageConverter { ); function loadDefaultTables() { - $this->mTables = array(); - $this->mTables['kk-kz'] = $this->mLatinToCyrillic; - $this->mTables['kk-tr'] = $this->mCyrillicToLatin; - $this->mTables['kk-cn'] = $this->mCyrillicToArabic; - $this->mTables['kk'] = array(); + $this->mTables = array( + 'kk-kz' => new ReplacementArray( $this->mLatinToCyrillic ), + 'kk-tr' => new ReplacementArray( $this->mCyrillicToLatin ), + 'kk-cn' => new ReplacementArray( $this->mCyrillicToArabic ), + 'kk' => new ReplacementArray() + ); } /* diff --git a/languages/classes/LanguageSr.php b/languages/classes/LanguageSr.php index 412463f88b89..fadfb35c1b02 100644 --- a/languages/classes/LanguageSr.php +++ b/languages/classes/LanguageSr.php @@ -53,12 +53,13 @@ class SrConverter extends LanguageConverter { ); function loadDefaultTables() { - $this->mTables = array(); - $this->mTables['sr-ec'] = $this->mToCyrillics; - $this->mTables['sr-jc'] = $this->mToCyrillics; - $this->mTables['sr-el'] = $this->mToLatin; - $this->mTables['sr-jl'] = $this->mToLatin; - $this->mTables['sr'] = array(); + $this->mTables = array( + 'sr-ec' => new ReplacementArray( $this->mToCyrillics ), + 'sr-jc' => new ReplacementArray( $this->mToCyrillics), + 'sr-el' => new ReplacementArray( $this->mToLatin), + 'sr-jl' => new ReplacementArray( $this->mToLatin), + 'sr' => new ReplacementArray() + ); } /* rules should be defined as -{ekavian | iyekavian-} -or- @@ -139,7 +140,7 @@ class SrConverter extends LanguageConverter { $matches = preg_split($reg, $text, -1, PREG_SPLIT_OFFSET_CAPTURE); $m = array_shift($matches); - $ret = strtr($m[0], $this->mTables[$toVariant]); + $ret = $this->mTables[$toVariant]->replace( $m[0] ); $mstart = $m[1]+strlen($m[0]); foreach($matches as $m) { $ret .= substr($text, $mstart, $m[1]-$mstart); @@ -149,8 +150,6 @@ class SrConverter extends LanguageConverter { return $ret; } - - } class LanguageSr extends LanguageSr_ec { diff --git a/languages/classes/LanguageZh.php b/languages/classes/LanguageZh.php index c34315ac1115..4f8a285a529f 100644 --- a/languages/classes/LanguageZh.php +++ b/languages/classes/LanguageZh.php @@ -9,17 +9,18 @@ require_once( dirname(__FILE__).'/LanguageZh_cn.php' ); class ZhConverter extends LanguageConverter { function loadDefaultTables() { require( "includes/ZhConversion.php" ); - $this->mTables = array(); - $this->mTables['zh-cn'] = $zh2CN; - $this->mTables['zh-tw'] = $zh2TW; - $this->mTables['zh-sg'] = array_merge($zh2CN, $zh2SG); - $this->mTables['zh-hk'] = array_merge($zh2TW, $zh2HK); - $this->mTables['zh'] = array(); + $this->mTables = array( + 'zh-cn' => new ReplacementArray( $zh2CN ), + 'zh-tw' => new ReplacementArray( $zh2TW ), + 'zh-sg' => new ReplacementArray( array_merge($zh2CN, $zh2SG) ), + 'zh-hk' => new ReplacementArray( array_merge($zh2TW, $zh2HK) ), + 'zh' => new ReplacementArray + ); } function postLoadTables() { - $this->mTables['zh-sg'] = array_merge($this->mTables['zh-cn'], $this->mTables['zh-sg']); - $this->mTables['zh-hk'] = array_merge($this->mTables['zh-tw'], $this->mTables['zh-hk']); + $this->mTables['zh-sg']->merge( $this->mTables['zh-cn'] ); + $this->mTables['zh-hk']->merge( $this->mTables['zh-tw'] ); } /* there shouldn't be any latin text in Chinese conversion, so no need diff --git a/maintenance/namespace2sql.php b/maintenance/namespace2sql.php index 8084bfec60a3..081f609965ab 100644 --- a/maintenance/namespace2sql.php +++ b/maintenance/namespace2sql.php @@ -6,8 +6,8 @@ require_once( "commandLine.inc" ); for ($i = -2; $i < 16; ++$i) { - $nsname = wfStrencode( $wgLang->getNsText( $i ) ); - $dbname = wfStrencode( $wgDBname ); + $nsname = mysql_escape_string( $wgLang->getNsText( $i ) ); + $dbname = mysql_escape_string( $wgDBname ); print "INSERT INTO ns_name(ns_db, ns_num, ns_name) VALUES('$dbname', $i, '$nsname');\n"; } |