MediaWiki namespace
authorTim Starling <tstarling@users.mediawiki.org>
Sun, 21 Sep 2003 13:10:10 +0000 (13:10 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Sun, 21 Sep 2003 13:10:10 +0000 (13:10 +0000)
docs/memcached.doc
includes/Article.php
includes/DatabaseFunctions.php
includes/DefaultSettings.php
includes/GlobalFunctions.php
includes/MagicWord.php
includes/OutputPage.php
install.php
languages/Language.php
maintenance/tables.sql
update.php

index 85a74a0..12a26b3 100644 (file)
@@ -109,5 +109,11 @@ LinkCache:
        set in: LinkCache::addLink()
        cleared by: LinkCache::clearBadLink()
                should be cleared on page deletion and rename
-
+MediaWiki namespace:
+       key: $wgDBname:MediaWiki:title:$title
+       ex: wikidb:MediaWiki:title:Blockedtext
+       stores: string
+       set in: wfMsg()
+       cleared by: Article::editUpdates()
+       
 ... more to come ...
index ba9d11f..269b193 100644 (file)
@@ -953,7 +953,7 @@ class Article {
 
        /* private */ function editUpdates( $text )
        {
-               global $wgDeferredUpdateList;
+               global $wgDeferredUpdateList, $wgDBname, $wgMemc;
 
                wfSeedRandom();
                if ( 0 == mt_rand( 0, 999 ) ) {
@@ -976,6 +976,11 @@ class Article {
                        $u = new UserTalkUpdate( 1, $this->mTitle->getNamespace(),
                          $this->mTitle->getDBkey() );
                        array_push( $wgDeferredUpdateList, $u );
+
+                       if ( $this->getNamespace == NS_MEDIAWIKI ) {
+                               $key = "$wgDBname:MediaWiki:title:" . $this->mTitle->getDBkey();
+                               $wgMemc->delete( $key );
+                       }
                }
        }
 
@@ -1055,6 +1060,11 @@ class Article {
                } else {
                        $text = preg_replace( $p2, "[[\\1 ({$context})|\\1]]", $text );
                }
+               
+               # {{SUBST:xxx}} variables
+               #
+               $mw =& MagicWord::get( MAG_SUBST );
+               $text = $mw->substituteCallback( $text, "replaceMsgVar" );
 
                return $text;
        }
index 3206feb..cdee256 100644 (file)
@@ -13,9 +13,9 @@ function wfGetDB( $altuser = "", $altpassword = "", $altserver = "", $altdb = ""
 {
        global $wgDBserver, $wgDBuser, $wgDBpassword;
        global $wgDBname, $wgDBconnection, $wgEmergencyContact;
-
-       $noconn = str_replace( "$1", $wgDBserver, wfMsg( "noconnect" ) );
-       $nodb = str_replace( "$1", $wgDBname, wfMsg( "nodb" ) );
+       
+       $noconn = str_replace( "$1", $wgDBserver, wfMsgNoDB( "noconnect" ) );
+       $nodb = str_replace( "$1", $wgDBname, wfMsgNoDB( "nodb" ) );
 
        $helpme = "\n<p>If this error persists after reloading and clearing " .
          "your browser cache, please notify the <a href=\"mailto:" .
@@ -55,7 +55,7 @@ function wfEmergencyAbort( $msg = "" ) {
        global $wgTitle, $wgUseFileCache, $title, $wgOutputEncoding;
        
        header( "Content-type: text/html; charset=$wgOutputEncoding" );
-       if($msg == "") $msg = wfMsg( "noconnect" );
+       if($msg == "") $msg = wfMsgNoDB( "noconnect" );
        $text = $msg;
 
        if($wgUseFileCache) {
@@ -65,14 +65,14 @@ function wfEmergencyAbort( $msg = "" ) {
                        if($title) {
                                $t = Title::newFromURL( $title );
                        } else {
-                               $t = Title::newFromText( wfMsg("mainpage") );
+                               $t = Title::newFromText( wfMsgNoDB( "mainpage" ) );
                        }
                }
 
                $cache = new CacheManager( $t );
                if( $cache->isFileCached() ) {
                        $msg = "<p style='color: red'><b>$msg<br>\n" .
-                               wfMsg( "cachederror" ) . "</b></p>\n";
+                               wfMsgNoDB( "cachederror" ) . "</b></p>\n";
                        
                        $tag = "<div id='article'>";
                        $text = str_replace(
@@ -98,7 +98,6 @@ function wfQuery( $sql, $db, $fname = "" )
        global $wgLastDatabaseQuery, $wgOut;
 ##     wfProfileIn( "wfQuery" );
        $wgLastDatabaseQuery = $sql;
-
        $conn = wfGetDB();
        $ret = mysql_query( $sql, $conn );
 
index de10268..c61486b 100644 (file)
@@ -61,6 +61,10 @@ $wgLocalInterwiki   = "w";
 $wgShowIPinHeader      = true; # For non-logged in users
 $wgUseDynamicDates     = true; # Allows the user to pick their preferred date format
 
+# Translation using MediaWiki: namespace
+# Not recommended unless memcached is installed
+$wgUseDatabaseMessages = false;
+
 # Miscellaneous configuration settings
 #
 $wgReadOnlyFile         = "{$wgUploadDirectory}/lock_yBgMBwiR";
@@ -70,6 +74,8 @@ $wgReadOnly             = false;
 $wgSqlLogFile           = "{$wgUploadDirectory}/sqllog_mFhyRe6";
 $wgLogQueries           = false;
 $wgUseBetterLinksUpdate = true;
+
+# User rights settings
 $wgSysopUserBans        = true; # Allow sysops to ban logged-in users
 $wgIPBlockExpiration    = 86400; # IP blocks expire after this many seconds, 0=infinite
 $wgUserBlockExpiration  = 0; # As above, but for logged-in users
index 195e4b7..57f89cc 100644 (file)
@@ -173,37 +173,82 @@ function wfReadOnly()
 }
 
 $wgReplacementKeys = array( "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" );
-function wfMsg( $key )
-{
-       global $wgLang, $wgReplacementKeys;
-       $message = $wgLang->getMessage( $key );
+
+function wfMsg( $key ) {
+       $args = func_get_args();
+       if ( count( $args ) ) {
+               array_shift( $args );
+       }
+       return wfMsgReal( $key, $args, true );
+}
+
+function wfMsgNoDB( $key ) {
+       $args = func_get_args();
+       if ( count( $args ) ) {
+               array_shift( $args );
+       }
+       return wfMsgReal( $key, $args, false );
+}
+
+function wfMsgReal( $key, $args, $useDB ) {
+       global $wgLang, $wgReplacementKeys, $wgMemc, $wgDBname;
+       global $wgUseDatabaseMessages;
+               
+       static $l1cache = array();
+       $fname = "wfMsg";
+       $message = false;
+       $l1hit = false;
        
-       if ( $message{0} == ":" ) {
-               # Get message from the database
-               $message = substr( $message, 1 );
-               $title = Title::newFromText( $message );
-               $dbKey = $title->getDBkey();
-               $ns = $title->getNamespace();
-               $sql = "SELECT cur_text FROM cur WHERE cur_namespace=$ns AND cur_title='$dbKey'";
-               $res = wfQuery( $sql, DB_READ, $fname );
-               if( ( $s = wfFetchObject( $res ) ) and ( $s->cur_text != "" ) ) {
-                       $message = $s->cur_text;
-                       # filter out a comment at the top if there is one
-                       $commentPos = strpos( $message, "__START__" );
-                       if ( $commentPos !== false ) {
-                               $message = substr( $message, $commentPos + strlen( "__START__" ) );
-                               wfDebug( "Comment filtered at pos $commentPos, \"$message\"\n" );
+       # Check for DB suppression
+       if ( !$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 );
+               }
+               $l1hit = true;
+       }
+
+       # Try memcached
+       if ( $message === false ) {
+               $titleObj = Title::newFromText( $key );
+               $title = $titleObj->getDBkey();
+               $mcKey = "$wgDBname:MediaWiki:title:$title";
+               $message = $wgMemc->get( $mcKey );
+       }
+
+       # Try database
+       if ( $message === false) {
+               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 );
                        }
-               } else {
-                       # if the page doesn't exist, just make a link to where it should be
-                       $message = "[[$message]]";
-               }       
-               wfFreeResult( $res );
+               }
        }
-       if( func_num_args() > 1 ) {
-               $reps = func_get_args();
-               array_shift( $reps );
-               $message = str_replace( $wgReplacementKeys, $reps, $message );
+
+       # Finally, try the array in $wgLang
+       if ( $message === false ) {
+               $message = $wgLang->getMessage( $key );
+               $l1cache[$key] = false;
+       } elseif ( !$l1hit && $wgUseDatabaseMessages) {
+               $l1cache[$key] = $message;
+       }
+       
+       # Replace arguments
+       if( count( $args ) ) {
+               $message = str_replace( $wgReplacementKeys, $args, $message );
        }
 
        if ( "" == $message ) {
@@ -590,4 +635,14 @@ 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] ) );
+       return $text;
+}
+
 ?>
index 714e885..dc98d9d 100644 (file)
@@ -15,7 +15,7 @@
 
 class MagicWord {
        /*private*/ var $mId, $mSynonyms, $mCaseSensitive, $mRegex;
-       /*private*/ var $mRegexStart, $mBaseRegex;
+       /*private*/ var $mRegexStart, $mBaseRegex, $mVariableRegex;
        
        function MagicWord($id = 0, $syn = "", $cs = false) 
        {
@@ -24,6 +24,7 @@ class MagicWord {
                $this->mCaseSensitive = $cs;
                $this->mRegex = "";
                $this->mRegexStart = "";
+               $this->mVariableRegex = "";
        }
 
        /*static*/ function &get( $id )
@@ -53,6 +54,8 @@ 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 );
+               wfDebug( "{$this->mVariableRegex}\n" );
        }
        
        function getRegex()
@@ -100,6 +103,23 @@ class MagicWord {
        {
                return preg_replace( $this->getRegex(), $replacement, $subject );
        }
+
+       function substituteCallback( $text, $callback ) {
+               $regex = $this->getVariableRegex();
+               return preg_replace_callback( $this->getVariableRegex(), $callback, $text );
+       }
+
+       function getVariableRegex()
+       {
+               if ( $this->mVariableRegex == "" ) {
+                       $this->initRegex();
+               } 
+               return $this->mVariableRegex;
+       }
+
+       function getSynonym( $i ) {
+               return $this->mSynonyms[$i];
+       }
 }
 
 /*private*/ function pregRemoveAndRecord( $match )
index 3919d21..284d155 100644 (file)
@@ -428,28 +428,29 @@ class OutputPage {
        function databaseError( $fname )
        {
                global $wgUser, $wgCommandLineMode;
-
-               $this->setPageTitle( wfMsg( "databaseerror" ) );
+               
+               $this->setPageTitle( wfMsgNoDB( "databaseerror" ) );
                $this->setRobotpolicy( "noindex,nofollow" );
                $this->setArticleFlag( false );
 
                if ( $wgCommandLineMode ) {
-                       $msg = wfMsg( "dberrortextcl" );
+                       $msg = wfMsgNoDB( "dberrortextcl" );
                } else {
-                       $msg = wfMsg( "dberrortextcl" );
+                       $msg = wfMsgNoDB( "dberrortextcl" );
                }
+
                $msg = str_replace( "$1", htmlspecialchars( wfLastDBquery() ), $msg );
                $msg = str_replace( "$2", htmlspecialchars( $fname ), $msg );
                $msg = str_replace( "$3", wfLastErrno(), $msg );
                $msg = str_replace( "$4", htmlspecialchars( wfLastError() ), $msg );
-
+               
                if ( $wgCommandLineMode ) {
-                       print $msg;
+                       print "$msg\n";
                        exit();
                }
                $sk = $wgUser->getSkin();
-               $shlink = $sk->makeKnownLink( wfMsg( "searchhelppage" ),
-                 wfMsg( "searchingwikipedia" ) );
+               $shlink = $sk->makeKnownLink( wfMsgNoDB( "searchhelppage" ),
+                 wfMsgNoDB( "searchingwikipedia" ) );
                $msg = str_replace( "$5", $shlink, $msg );
 
                $this->mBodytext = $msg;
@@ -1246,6 +1247,14 @@ $t[] = "</table>" ;
                        $v = wfNumberOfArticles();
                        $text = $mw->replace( $v, $text );
                }
+
+               # The callbacks are in GlobalFunctions.php
+               $mw =& MagicWord::get( MAG_MSG );
+               $text = $mw->substituteCallback( $text, "replaceMsgVar" );
+
+               $mw =& MagicWord::get( MAG_MSGNW );
+               $text = $mw->substituteCallback( $text, "replaceMsgVarNw" );
+
                wfProfileOut();
                return $text;
        }
index 235cc93..585e2cf 100644 (file)
@@ -21,6 +21,7 @@ if ( ! ( is_readable( "./LocalSettings.php" )
 $DP = "./includes";
 include_once( "./LocalSettings.php" );
 include_once( "./AdminSettings.php" );
+include_once( "./maintenance/InitialiseMessages.php" );
 
 if ( $wgUseTeX && ( ! is_executable( "./math/texvc" ) ) ) {
        print "To use math functions, you must first compile texvc by\n" .
@@ -272,26 +273,30 @@ function populatedata() {
        }
        
        $wns = Namespace::getWikipedia();
-       $ulp = addslashes( wfMsg( "uploadlogpage" ) );
-       $dlp = addslashes( wfMsg( "dellogpage" ) );
+       $ulp = addslashes( wfMsgNoDB( "uploadlogpage" ) );
+       $dlp = addslashes( wfMsgNoDB( "dellogpage" ) );
 
        $sql = "DELETE FROM cur";
        wfQuery( $sql, DB_WRITE, $fname );
 
        $sql = "INSERT INTO cur (cur_namespace,cur_title,cur_text," .
          "cur_restrictions) VALUES ({$wns},'{$ulp}','" .
-         wfStrencode( wfMsg( "uploadlogpagetext" ) ) . "','sysop')";
+         wfStrencode( wfMsgNoDB( "uploadlogpagetext" ) ) . "','sysop')";
        wfQuery( $sql, DB_WRITE, $fname );
 
        $sql = "INSERT INTO cur (cur_namespace,cur_title,cur_text," .
          "cur_restrictions) VALUES ({$wns},'{$dlp}','" .
-         wfStrencode( wfMsg( "dellogpagetext" ) ) . "','sysop')";
+         wfStrencode( wfMsgNoDB( "dellogpagetext" ) ) . "','sysop')";
        wfQuery( $sql, DB_WRITE, $fname );
-
+       
+       $titleobj = Title::newFromText( wfMsgNoDB( "mainpage" ) );
+       $title = $titleobj->getDBkey();
        $sql = "INSERT INTO cur (cur_namespace,cur_title,cur_text) " .
-         "VALUES (0,'" . wfStrencode( wfMsg( "mainpage" ) ) . "','" .
-         wfStrencode( wfMsg( "mainpagetext" ) ) . "')";
+         "VALUES (0,'$title','" .
+         wfStrencode( wfMsgNoDB( "mainpagetext" ) ) . "')";
        wfQuery( $sql, DB_WRITE, $fname );
+       
+       initialiseMessages();
 }
 
 ?>
index 144d1f5..8998aef 100644 (file)
@@ -14,6 +14,8 @@ define("NS_WP", 4);
 define("NS_WP_TALK", 5);
 define("NS_IMAGE", 6);
 define("NS_IMAGE_TALK", 7);
+define("NS_MEDIAWIKI", 8);
+define("NS_MEDIAWIKI_TALK", 9);
 
 # Magic words
 define("MAG_REDIRECT", 0);
@@ -27,6 +29,9 @@ define("MAG_CURRENTYEAR", 7);
 define("MAG_CURRENTTIME", 8);
 define("MAG_NUMBEROFARTICLES", 9);
 define("MAG_CURRENTMONTHNAMEGEN", 10);
+define("MAG_MSG", 11);
+define("MAG_SUBST", 12);
+define("MAG_MSGNW", 13);
 
 #--------------------------------------------------------------------------
 # Language-specific text
@@ -48,7 +53,9 @@ define("MAG_CURRENTMONTHNAMEGEN", 10);
        4       => "Wikipedia",
        5       => "Wikipedia_talk",
        6       => "Image",
-       7       => "Image_talk"
+       7       => "Image_talk",
+       8       => "MediaWiki",
+       9       => "MediaWiki_talk"
 );
 
 /* private */ $wgDefaultUserOptionsEn = array(
@@ -285,6 +292,9 @@ this</a> (alternative: like this<a href=\"\" class=\"internal\">?</a>).",
     MAG_CURRENTTIME          => array( 1,    "{{CURRENTTIME}}"        ),
     MAG_NUMBEROFARTICLES     => array( 1,    "{{NUMBEROFARTICLES}}"   ),
     MAG_CURRENTMONTHNAMEGEN  => array( 1,    "{{CURRENTMONTHNAMEGEN}}"),
+       MAG_MSG                  => array( 1,    "{{MSG:$1}}"             ),
+       MAG_SUBST                => array( 1,    "{{SUBST:$1}}"           ),
+    MAG_MSGNW                => array( 1,    "{{MSGNW:$1}}"           )
 );
        
 # All special pages have to be listed here: a description of ""
@@ -1223,6 +1233,10 @@ wiki running MediaWiki software, transformed, or just kept for your private
 amusement.",
 "exportcuronly"        => "Include only the current revision, not the full history",
 
+# Namespace 8 related
+
+"allmessages"  => "All_messages",
+"allmessagestext"      => "This is a list of all messages available in the MediaWiki: namespace"
 );
 
 #--------------------------------------------------------------------------
@@ -1426,6 +1440,12 @@ class Language {
                return $wgAllMessagesEn[$key];
        }
        
+       function getAllMessages()
+       {
+               global $wgAllMessagesEn;
+               return $wgAllMessagesEn;
+       }
+
        function iconv( $in, $out, $string ) {
                # For most languages, this is a wrapper for iconv
                return iconv( $in, $out, $string );
index 43c2a27..201a946 100644 (file)
@@ -114,7 +114,7 @@ CREATE TABLE ipblocks (
   ipb_reason tinyblob NOT NULL default '',
   ipb_timestamp char(14) binary NOT NULL default '',
   ipb_auto tinyint(1) NOT NULL default '0',
-  UNIQUE KEY ipb_id
+  UNIQUE KEY ipb_id (ipb_id)
 ) TYPE=MyISAM PACK_KEYS=1;
 
 DROP TABLE IF EXISTS image;
index 4be774f..6653591 100644 (file)
@@ -25,13 +25,15 @@ set_time_limit( 0 );
 
 include_once( "Version.php" );
 include_once( "{$IP}/Setup.php" );
+include_once( "./maintenance/InitialiseMessages.php" );
+
 $wgTitle = Title::newFromText( "Update script" );
 $wgCommandLineMode = true;
 $wgAlterSpecs = array();
 
 do_revision_updates();
-
 alter_ipblocks();
+initialiseMessages();
 
 #
 # Run ALTER TABLE queries.