Various fixes, see the version of [[m:Development status]] before this commit for...
[lhc/web/wiklou.git] / includes / GlobalFunctions.php
index 9f28e23..42dd1a1 100644 (file)
@@ -150,6 +150,7 @@ function wfReadOnly()
 
 $wgReplacementKeys = array( "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" );
 
+# Get a message from anywhere
 function wfMsg( $key ) {
        $args = func_get_args();
        if ( count( $args ) ) {
@@ -158,6 +159,7 @@ function wfMsg( $key ) {
        return wfMsgReal( $key, $args, true );
 }
 
+# Get a message from the language file
 function wfMsgNoDB( $key ) {
        $args = func_get_args();
        if ( count( $args ) ) {
@@ -166,69 +168,83 @@ function wfMsgNoDB( $key ) {
        return wfMsgReal( $key, $args, false );
 }
 
+# Really get a message
 function wfMsgReal( $key, $args, $useDB ) {
        global $wgLang, $wgReplacementKeys, $wgMemc, $wgDBname;
-       global $wgUseDatabaseMessages;
-               
-       static $l1cache = array();
+       global $wgUseDatabaseMessages, $wgUseMemCached, $wgOut;
+       global $wgAllMessagesEn, $wgLanguageCode;
+
        $fname = "wfMsg";
-       $message = false;
-       $l1hit = false;
+       wfProfileIn( $fname );
        
-       # Check for DB suppression
-       if ( !$wgUseDatabaseMessages || !$useDB ) {
+       static $messageCache = false;
+       $memcKey = "$wgDBname:messages";
+       $fname = "wfMsg";
+       $message = false;
+
+       # newFromText is too slow!
+       $title = ucfirst( $key );
+       if ( $messageCache ) {
+               $message = $messageCache[$title];
+       } elseif ( !$wgUseDatabaseMessages || !$useDB ) {
                $message = $wgLang->getMessage( $key );
        }
 
-       # Try L1 cache
-       if ( $message === false && array_key_exists( $key, $l1cache ) ) {
-               $message  = $l1cache[$key];
-               if ( $message === false ) {
-                       $message = $wgLang->getMessage( $key );
+       if ( !$message && $wgUseMemCached ) {
+               # Try memcached
+               if ( !$messageCache ) {
+                       $messageCache = $wgMemc->get( $memcKey );
                }
-               $l1hit = true;
-       }
-
-       # Try memcached
-       if ( $message === false ) {
-               $titleObj = Title::newFromText( $key );
-               $title = $titleObj->getDBkey();
-               $mcKey = "$wgDBname:MediaWiki:title:$title";
-               $message = $wgMemc->get( $mcKey );
+               
+               # If there's nothing in memcached, load all the messages from the database
+               # This should only happen on server reset -- ordinary changes should update
+               # memcached in editUpdates()
+               if ( !$messageCache ) {
+                       # Other threads don't need to load the messages if another thread is doing it.
+                       $wgMemc->set( $memcKey, "loading", time() + 60 );
+                       $messageCache = wfLoadAllMessages();
+                       # Save in memcached
+                       $wgMemc->set( $memcKey, $messageCache, time() + 3600 );
+                       
+                       
+               }
+               if ( is_array( $messageCache ) && array_key_exists( $title, $messageCache ) ) {
+                       $message = $messageCache[$title];
+               } 
        }
 
-       # Try database
-       if ( $message === false) {
+       # If there was no MemCached, load each message from the DB individually
+       if ( !$message ) {
                if ( $useDB ) {
                        $sql = "SELECT cur_text FROM cur WHERE cur_namespace=" . NS_MEDIAWIKI . 
                                " AND cur_title='$title'";
                        $res = wfQuery( $sql, DB_READ, $fname );
 
                        if ( wfNumRows( $res ) ) {
-                               # Got it from the database, now store in MemCached
                                $obj = wfFetchObject( $res );
                                $message = $obj->cur_text;
                                wfFreeResult( $res );
-                               $wgMemc->set( $key, $message, time() + 1800 );
                        }
                }
        }
 
-       # Finally, try the array in $wgLang
-       if ( $message === false ) {
+       # Try the array in $wgLang
+       if ( !$message ) {
                $message = $wgLang->getMessage( $key );
-               $l1cache[$key] = false;
-       } elseif ( !$l1hit && $wgUseDatabaseMessages) {
-               $l1cache[$key] = $message;
+       } 
+
+       # Try the English array
+       if ( !$message && $wgLanguageCode != "en" ) {
+               $message = Language::getMessage( $key );
        }
        
        # Replace arguments
        if( count( $args ) ) {
                $message = str_replace( $wgReplacementKeys, $args, $message );
        }
-
-       if ( "" == $message ) {
-               # Let's at least _try_ to be graceful about this.
+       wfProfileOut( $fname );
+       if ( !$message ) {
+               # Failed, message does not exist
                return "<$key>";
        }
        return $message;
@@ -611,14 +627,32 @@ function wfCheckLimits( $deflimit = 50, $optionname = "rclimit" ) {
        return array( $limit, $offset );
 }
 
-# Used in OutputPage::replaceVariables and Article:pstPass2
-function replaceMsgVar( $matches ) {
-       return wfMsg( $matches[1] );
-}
-
-function replaceMsgVarNw( $matches ) {
-       $text = htmlspecialchars( wfMsg( $matches[1] ) );
+# Escapes the given text so that it may be output using addWikiText() 
+# without any linking, formatting, etc. making its way through. This 
+# is achieved by substituting certain characters with HTML entities.
+# As required by the callers, <nowiki> is not used. It currently does
+# not filter out characters which have special meaning only at the
+# start of a line, such as "*".
+function wfEscapeWikiText( $text )
+{
+       $text = str_replace( 
+               array( '[',     "'",     'ISBN '    , '://'),
+               array( '&#91;', '&#39;', 'ISBN&#32;', '&#58;//'),
+               htmlspecialchars($text) );
        return $text;
 }
 
+# Loads the entire MediaWiki namespace, retuns the array
+function wfLoadAllMessages()
+{
+       $sql = "SELECT cur_title,cur_text FROM cur WHERE cur_namespace=" . NS_MEDIAWIKI;
+       $res = wfQuery( $sql, DB_READ, $fname );
+       
+       $messages = array();
+       for ( $row = wfFetchObject( $res ); $row; $row = wfFetchObject( $res ) ) {
+               $messages[$row->cur_title] = $row->cur_text;
+       }
+       wfFreeResult( $res );
+       return $messages;
+}
 ?>