Various fixes, see the version of [[m:Development status]] before this commit for...
authorTim Starling <tstarling@users.mediawiki.org>
Sun, 2 Nov 2003 13:57:24 +0000 (13:57 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Sun, 2 Nov 2003 13:57:24 +0000 (13:57 +0000)
docs/memcached.doc
includes/Article.php
includes/DatabaseFunctions.php
includes/GlobalFunctions.php
includes/MagicWord.php
includes/OutputPage.php
includes/Profiling.php
languages/Language.php
maintenance/InitialiseMessages.php
maintenance/rebuildlinks.inc

index 93e402d..eba62ca 100644 (file)
@@ -113,6 +113,6 @@ MediaWiki namespace:
        key: $wgDBname:messages
        ex: wikidb:messages
        stores: an array where the keys are DB keys and the values are messages
-       set in: wfMsg()
-       cleared by: Article::editUpdates()
+       set in: wfMsg(), Article::editUpdates() both call wfLoadAllMessages()
+       cleared by: nothing
 ... more to come ...
index 43fda88..4c6d3b5 100644 (file)
@@ -97,6 +97,7 @@ class Article {
                $t = $this->mTitle->getPrefixedText();
                if ( $oldid ) { $t .= ",oldid={$oldid}"; }
                if ( $redirect ) { $t .= ",redirect={$redirect}"; }
+
                $this->mContent = str_replace( "$1", $t, wfMsg( "missingarticle" ) );
 
                if ( ! $oldid ) {       # Retrieve current version
@@ -106,11 +107,13 @@ class Article {
                        $sql = "SELECT " .
                          "cur_text,cur_timestamp,cur_user,cur_counter,cur_restrictions,cur_touched " .
                          "FROM cur WHERE cur_id={$id}";
+                       wfDebug( "$sql\n" );
                        $res = wfQuery( $sql, DB_READ, $fname );
-                       if ( 0 == wfNumRows( $res ) ) { return; }
+                       if ( 0 == wfNumRows( $res ) ) { 
+                               return; 
+                       }
 
                        $s = wfFetchObject( $res );
-
                        # If we got a redirect, follow it (unless we've been told
                        # not to by either the function parameter or the query
                        if ( ( "no" != $redirect ) && ( false == $noredir ) &&
@@ -146,6 +149,7 @@ class Article {
                                        }
                                }
                        }
+
                        $this->mContent = $s->cur_text;
                        $this->mUser = $s->cur_user;
                        $this->mCounter = $s->cur_counter;
@@ -989,7 +993,12 @@ class Article {
                        array_push( $wgDeferredUpdateList, $u );
 
                        if ( $this->getNamespace == NS_MEDIAWIKI ) {
-                               $wgMemc->delete( "$wgDBname:messages" );
+                               $messageCache = $wgMemc->get( "$wgDBname:messages" );
+                               if (!$messageCache) {
+                                       $messageCache = wfLoadAllMessages();
+                               }
+                               $messageCache[$title] = $text;
+                               $wgMemc->set( "$wgDBname:messages" );
                        }
                }
        }
@@ -1074,7 +1083,7 @@ class Article {
                # {{SUBST:xxx}} variables
                #
                $mw =& MagicWord::get( MAG_SUBST );
-               $text = $mw->substituteCallback( $text, "replaceMsgVar" );
+               $text = $mw->substituteCallback( $text, "wfReplaceSubstVar" );
 
                return $text;
        }
@@ -1131,4 +1140,8 @@ class Article {
 
 }
 
+function wfReplaceSubstVar( $matches ) {
+       return wfMsg( $matches[1] );
+}
+
 ?>
index cdee256..2d74af4 100644 (file)
@@ -97,6 +97,12 @@ function wfQuery( $sql, $db, $fname = "" )
 {
        global $wgLastDatabaseQuery, $wgOut;
 ##     wfProfileIn( "wfQuery" );
+
+       if ( !is_numeric( $db ) ) {
+               # Someone has tried to call this the old way
+               $wgOut->fatalError( wfMsgNoDB( "wrong_wfQuery_params" ) );
+       }
+       
        $wgLastDatabaseQuery = $sql;
        $conn = wfGetDB();
        $ret = mysql_query( $sql, $conn );
index 3217588..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,10 +168,11 @@ function wfMsgNoDB( $key ) {
        return wfMsgReal( $key, $args, false );
 }
 
+# Really get a message
 function wfMsgReal( $key, $args, $useDB ) {
        global $wgLang, $wgReplacementKeys, $wgMemc, $wgDBname;
        global $wgUseDatabaseMessages, $wgUseMemCached, $wgOut;
-       global $wgAllMessagesEn;
+       global $wgAllMessagesEn, $wgLanguageCode;
 
        $fname = "wfMsg";
        wfProfileIn( $fname );
@@ -194,17 +197,16 @@ function wfMsgReal( $key, $args, $useDB ) {
                }
                
                # 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 );
-                       
-                       $sql = "SELECT cur_title,cur_text FROM cur WHERE cur_namespace=" . NS_MEDIAWIKI;
-                       $res = wfQuery( $sql, DB_READ, $fname );
-                       for ( $row = wfFetchObject( $res ); $row; $row = wfFetchObject( $res ) ) {
-                               $messageCache[$row->cur_title] = $row->cur_text;
-                       }
+                       $messageCache = wfLoadAllMessages();
                        # Save in memcached
                        $wgMemc->set( $memcKey, $messageCache, time() + 3600 );
+                       
+                       
                }
                if ( is_array( $messageCache ) && array_key_exists( $title, $messageCache ) ) {
                        $message = $messageCache[$title];
@@ -226,10 +228,15 @@ function wfMsgReal( $key, $args, $useDB ) {
                }
        }
 
-       # Finally, try the array in $wgLang
+       # Try the array in $wgLang
        if ( !$message ) {
                $message = $wgLang->getMessage( $key );
        } 
+
+       # Try the English array
+       if ( !$message && $wgLanguageCode != "en" ) {
+               $message = Language::getMessage( $key );
+       }
        
        # Replace arguments
        if( count( $args ) ) {
@@ -237,7 +244,7 @@ function wfMsgReal( $key, $args, $useDB ) {
        }
        wfProfileOut( $fname );
        if ( !$message ) {
-               # Failed, message not translated
+               # Failed, message does not exist
                return "&lt;$key&gt;";
        }
        return $message;
@@ -620,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;
+}
 ?>
index b8d39da..91bc2c4 100644 (file)
@@ -54,7 +54,7 @@ class MagicWord {
                $case = $this->mCaseSensitive ? "" : "i";
                $this->mRegex = "/{$this->mBaseRegex}/{$case}";
                $this->mRegexStart = "/^{$this->mBaseRegex}/{$case}";
-               $this->mVariableRegex = str_replace( "\\$1", "([A-Za-z0-9]*)", $this->mRegex );
+               $this->mVariableRegex = str_replace( "\\$1", "([A-Za-z0-9_\-]*)", $this->mRegex );
        }
        
        function getRegex()
index adc63df..995187d 100644 (file)
@@ -938,7 +938,6 @@ $t[] = "</table>" ;
                        
                        else { # Invalid form; output directly
                                $s .= "[[" . $line ;
-                               wfProfileOut( "$fname-loop1" );
                                continue;
                        }
                        if(substr($m[1],0,1)=="/") { # subpage
@@ -1203,8 +1202,12 @@ $t[] = "</table>" ;
                $fname = "OutputPage::replaceVariables";
                wfProfileIn( $fname );
 
-               /* As with sigs, use server's local time --
-                  ensure this is appropriate for your audience! */
+               
+               # Basic variables
+               # See Language.php for the definition of each magic word
+
+               # As with sigs, this uses the server's local time -- ensure 
+               # this is appropriate for your audience!
                $v = date( "m" );
                $mw =& MagicWord::get( MAG_CURRENTMONTH );
                $text = $mw->replace( $v, $text );
@@ -1239,17 +1242,19 @@ $t[] = "</table>" ;
                        $text = $mw->replace( $v, $text );
                }
 
-               # The callbacks are in GlobalFunctions.php
+               # "Variables" with an additional parameter e.g. {{MSG:wikipedia}}
+               # The callbacks are at the bottom of this file
                $mw =& MagicWord::get( MAG_MSG );
-               $text = $mw->substituteCallback( $text, "replaceMsgVar" );
+               $text = $mw->substituteCallback( $text, "wfReplaceMsgVar" );
 
                $mw =& MagicWord::get( MAG_MSGNW );
-               $text = $mw->substituteCallback( $text, "replaceMsgVarNw" );
+               $text = $mw->substituteCallback( $text, "wfReplaceMsgnwVar" );
 
                wfProfileOut( $fname );
                return $text;
        }
 
+       # Cleans up HTML, removes dangerous tags and attributes
        /* private */ function removeHTMLtags( $text )
        {
                $fname = "OutputPage::removeHTMLtags";
@@ -1576,4 +1581,22 @@ $t[] = "</table>" ;
        }
 }
 
+# Regex callbacks, used in OutputPage::replaceVariables
+
+# Just get rid of the dangerous stuff
+# Necessary because replaceVariables is called after removeHTMLtags, 
+# and message text can come from any user
+function wfReplaceMsgVar( $matches ) {
+       global $wgOut;
+       $text = $wgOut->removeHTMLtags( wfMsg( $matches[1] ) );
+       return $text;
+}
+
+# Effective <nowiki></nowiki>
+# Not real <nowiki> because this is called after nowiki sections are processed
+function wfReplaceMsgnwVar( $matches ) {
+       $text = wfEscapeWikiText( wfMsg( $matches[1] ) );
+       return $text;
+}
+
 ?>
index ee82e4f..7be7028 100755 (executable)
@@ -48,15 +48,19 @@ class Profiler
                global $wgDebugProfiling;
                $bit = array_pop( $this->mWorkStack );
                
-               if ( $wgDebugProfiling ) {
-                       if ( $functionname == "close" ) {
-                               wfDebug( "Profile section ended by close(): {$bit[0]}\n" );
-                       } elseif ( $bit[0] != $functionname ) {
-                               wfDebug( "Profiling error: in({$bit[0]}), out($functionname)\n" );
+               if ( !$bit ) {
+                       wfDebug( "Profiling error, !\$bit: $functionname\n" );
+               } else {
+                       if ( $wgDebugProfiling ) {
+                               if ( $functionname == "close" ) {
+                                       wfDebug( "Profile section ended by close(): {$bit[0]}\n" );
+                               } elseif ( $bit[0] != $functionname ) {
+                                       wfDebug( "Profiling error: in({$bit[0]}), out($functionname)\n" );
+                               }
                        }
+                       array_push( $bit, microtime() );
+                       array_push( $this->mStack, $bit );
                }
-               array_push( $bit, microtime() );
-               array_push( $this->mStack, $bit );
        }
        
        function close() 
index 6cf4f84..9897a81 100644 (file)
@@ -349,6 +349,13 @@ this</a> (alternative: like this<a href=\"\" class=\"internal\">?</a>).",
        "Debug"                 => "Debugging information"
 );
 
+#-------------------------------------------------------------------
+# Default messages
+#-------------------------------------------------------------------
+# Allowed characters in keys are: A-Z, a-z, 0-9, underscore (_) and 
+# hyphen (-). If you need more characters, you may be able to change
+# the regex in MagicWord::initRegex
+
 /* private */ $wgAllMessagesEn = array(
 
 # Bits of text used by many pages:
@@ -496,6 +503,7 @@ an incorrectly linked inter-language or inter-wiki title.",
 because it slows the database down to the point that no one can use
 the wiki.",
 "perfdisabledsub" => "Here's a saved copy from $1:",
+"wrong_wfQuery_params" => "Incorrect parameters to wfQuery",
 
 # Login and logout pages
 #
index fcd8e90..1851834 100644 (file)
@@ -64,7 +64,7 @@ function getAllMessages()
                $mw = $mwObj->getSynonym( 0 );
                $mw = str_replace( "$1", $key, $mw );
 
-               $message = htmlspecialchars( $message );
+               $message = wfEscapeWikiText( $message );
                $navText .= 
 "<tr><td>
   [$wgServer$wgScript?title=MediaWiki:$title&action=edit $key]
index 7dd3dde..0c7169f 100644 (file)
@@ -12,23 +12,23 @@ function rebuildLinkTablesPass1()
        print "Rebuilding link tables (pass 1).\n";
 
        $sql = "DROP TABLE IF EXISTS rebuildlinks";
-       wfQuery( $sql );
+       wfQuery( $sql, DB_WRITE );
 
        $sql = "CREATE TABLE rebuildlinks (
   rl_f_id int(8) unsigned NOT NULL default 0,
   rl_f_title varchar(255) binary NOT NULL default '',
   rl_to varchar(255) binary NOT NULL default '',
   INDEX rl_to (rl_to) ) TYPE=MyISAM";
-       wfQuery( $sql );
+       wfQuery( $sql, DB_WRITE );
 
-       $sql = "LOCK TABLES cur READ, rebuildlinks WRITE";
-       wfQuery( $sql );
+       $sql = "LOCK TABLES cur READ, rebuildlinks WRITE, interwiki READ";
+       wfQuery( $sql, DB_WRITE );
 
        $sql = "DELETE FROM rebuildlinks";
-       wfQuery( $sql );
+       wfQuery( $sql, DB_WRITE );
 
        $sql = "SELECT cur_id,cur_namespace,cur_title,cur_text FROM cur";
-       $res = wfQuery( $sql );
+       $res = wfQuery( $sql, DB_WRITE );
        $total = wfNumRows( $res );
 
        $tc = Title::legalChars();
@@ -53,7 +53,7 @@ function rebuildLinkTablesPass1()
                                if ( 0 != $i ) { $sql .= ","; }
                                $sql .= "({$id},'{$title}','{$dest}')";
                        }
-                       wfQuery( $sql );
+                       wfQuery( $sql, DB_WRITE );
                }
                if ( ( ++$count % 1000 ) == 0 ) {
                        print "$count of $total articles scanned.\n";
@@ -63,7 +63,7 @@ function rebuildLinkTablesPass1()
        mysql_free_result( $res );
 
        $sql = "UNLOCK TABLES";
-       wfQuery( $sql );
+       wfQuery( $sql, DB_WRITE );
 }
 
 function rebuildLinkTablesPass2()
@@ -72,24 +72,24 @@ function rebuildLinkTablesPass2()
        $count = 0;
        print "Rebuilding link tables (pass 2).\n";
 
-       $sql = "LOCK TABLES cur READ, rebuildlinks READ, " .
+       $sql = "LOCK TABLES cur READ, rebuildlinks READ, interwiki READ, " .
          "links WRITE, brokenlinks WRITE, imagelinks WRITE";
-       wfQuery( $sql );
+       wfQuery( $sql, DB_WRITE );
 
        $sql = "DELETE FROM links";
-       wfQuery( $sql );
+       wfQuery( $sql, DB_WRITE );
 
        $sql = "DELETE FROM brokenlinks";
-       wfQuery( $sql );
+       wfQuery( $sql, DB_WRITE );
 
        $sql = "DELETE FROM links";
-       wfQuery( $sql );
+       wfQuery( $sql, DB_WRITE );
 
        $ins = $wgLang->getNsText( Namespace::getImage() );
        $inslen = strlen($ins)+1;
        $sql = "SELECT rl_f_title,rl_to FROM rebuildlinks " .
          "WHERE rl_to LIKE '$ins:%'";
-       $res = wfQuery( $sql );
+       $res = wfQuery( $sql, DB_WRITE );
 
        $sql = "INSERT INTO imagelinks (il_from,il_to) VALUES ";
        $sqlX = "";
@@ -106,12 +106,12 @@ function rebuildLinkTablesPass2()
        if ($sqlX != "") {
          $sql .= $sqlX;
          wfFreeResult( $res );
-         wfQuery( $sql );
+         wfQuery( $sql, DB_WRITE );
        }
 
        $sql = "SELECT DISTINCT rl_to FROM rebuildlinks " .
          "ORDER BY rl_to";
-       $res = wfQuery( $sql );
+       $res = wfQuery( $sql, DB_WRITE );
        $count = 0;
        $total = wfNumRows( $res );
 
@@ -124,7 +124,7 @@ function rebuildLinkTablesPass2()
 
                if ( 0 == $id ) {
                        $sql = "SELECT rl_f_id FROM rebuildlinks WHERE rl_to='{$to}'";
-                       $res2 = wfQuery( $sql );
+                       $res2 = wfQuery( $sql, DB_WRITE );
 
                        $sql = "INSERT INTO brokenlinks (bl_from,bl_to) VALUES ";
                        $first = true;
@@ -135,10 +135,10 @@ function rebuildLinkTablesPass2()
                                $sql .= "({$from},'{$to}')";
                        }
                        wfFreeResult( $res2 );
-                       if ( ! $first ) { wfQuery( $sql ); }
+                       if ( ! $first ) { wfQuery( $sql, DB_WRITE ); }
                } else {
                        $sql = "SELECT rl_f_title FROM rebuildlinks WHERE rl_to='{$to}'";
-                       $res2 = wfQuery( $sql );
+                       $res2 = wfQuery( $sql, DB_WRITE );
 
                        $sql = "INSERT INTO links (l_from,l_to) VALUES ";
                        $first = true;
@@ -149,7 +149,7 @@ function rebuildLinkTablesPass2()
                                $sql .= "('{$from}',{$id})";
                        }
                        wfFreeResult( $res2 );
-                       if ( ! $first ) { wfQuery( $sql ); }
+                       if ( ! $first ) { wfQuery( $sql, DB_WRITE ); }
                }
                if ( ( ++$count % 1000 ) == 0 ) {
                        print "$count of $total titles processed.\n";
@@ -158,9 +158,9 @@ function rebuildLinkTablesPass2()
        wfFreeResult( $res );
 
        $sql = "UNLOCK TABLES";
-       wfQuery( $sql );
+       wfQuery( $sql, DB_WRITE );
 
        $sql = "DROP TABLE rebuildlinks";
-       wfQuery( $sql );
+       wfQuery( $sql, DB_WRITE );
 }
 ?>