Improvements in MediaWiki namespace handling, enhanced rollback
authorTim Starling <tstarling@users.mediawiki.org>
Sun, 14 Dec 2003 14:29:35 +0000 (14:29 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Sun, 14 Dec 2003 14:29:35 +0000 (14:29 +0000)
includes/Article.php
includes/DefaultSettings.php
includes/GlobalFunctions.php
includes/Namespace.php
includes/Setup.php
includes/SpecialMovepage.php

index 0c3afaf..44d6a8d 100644 (file)
@@ -402,7 +402,7 @@ class Article {
                $this->showArticle( $text, wfMsg( "newarticle" ) );
        }
 
-       function updateArticle( $text, $summary, $minor, $watchthis, $section = "")
+       function updateArticle( $text, $summary, $minor, $watchthis, $section = "", $forceBot = false )
        {
                global $wgOut, $wgUser, $wgLinkCache;
                global $wgDBtransactions, $wgMwRedir;
@@ -478,13 +478,14 @@ class Article {
                        $res = wfQuery( $sql, DB_WRITE, $fname );
                        $oldid = wfInsertID( $res );
 
+                       $bot = (int)($wgUser->isBot() || $forceBot);
+                       
                        $sql = "INSERT INTO recentchanges (rc_timestamp,rc_cur_time," .
                          "rc_namespace,rc_title,rc_new,rc_minor,rc_bot,rc_cur_id,rc_user," .
                          "rc_user_text,rc_comment,rc_this_oldid,rc_last_oldid) VALUES (" .
                          "'{$now}','{$now}'," . $this->mTitle->getNamespace() . ",'" .
                          wfStrencode( $this->mTitle->getDBkey() ) . "',0,{$me2}," .
-                         ( $wgUser->isBot() ? 1 : 0 ) . "," .
-                         $this->getID() . "," . $wgUser->getID() . ",'" .
+                         "$bot," . $this->getID() . "," . $wgUser->getID() . ",'" .
                          wfStrencode( $wgUser->getName() ) . "','" .
                          wfStrencode( $summary ) . "',0,{$oldid})";
                        wfQuery( $sql, DB_WRITE, $fname );
@@ -705,7 +706,7 @@ class Article {
 
        function delete()
        {
-               global $wgUser, $wgOut;
+               global $wgUser, $wgOut, $wgMessageCache;
                global $wpConfirm, $wpReason, $image, $oldimage;
 
                # This code desperately needs to be totally rewritten
@@ -719,6 +720,12 @@ class Article {
                        return;
                }
 
+               # Can't delete cached MediaWiki namespace (i.e. vital messages)
+               if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI && $wgMessageCache->isCacheable( $this->mTitle->getDBkey() ) ) {
+                       $wgOut->fatalError( wfMsg( "cannotdelete" ) );
+                       return;
+               }
+
                # Better double-check that it hasn't been deleted yet!
                $wgOut->setPagetitle( wfMsg( "confirmdelete" ) );
                if ( ( "" == trim( $this->mTitle->getText() ) )
@@ -973,7 +980,10 @@ class Article {
                        $wgOut->readOnlyPage( $this->getContent() );
                        return;
                }
-
+               
+               # Secret enhanced rollback, marks edits rc_bot=1
+               $bot = !!$_REQUEST['bot'];
+               
                # Replace all this user's current edits with the next one down
                $tt = wfStrencode( $this->mTitle->getDBKey() );
                $n = $this->mTitle->getNamespace();
@@ -1007,7 +1017,7 @@ class Article {
                }
                
                # Get the last edit not by this guy
-               $sql = "SELECT old_text,old_user,old_user_text
+               $sql = "SELECT old_text,old_user,old_user_text,old_timestamp
                FROM old USE INDEX (name_title_timestamp)
                WHERE old_namespace={$n} AND old_title='{$tt}'
                AND (old_user <> {$uid} OR old_user_text <> '{$ut}')
@@ -1020,19 +1030,27 @@ class Article {
                        return;
                }
                $s = wfFetchObject( $res );
-       
+               
+               if ( $bot ) {
+                       # Mark all reverted edits as bot
+                       $sql = "UPDATE recentchanges SET rc_bot=1 WHERE
+                               rc_cur_id=$pid AND rc_user=$uid AND rc_timestamp > '{$s->old_timestamp}'";
+                       wfQuery( $sql, DB_WRITE, $fname );
+               }
+
                # Save it!
                $newcomment = wfMsg( "revertpage", $s->old_user_text );
                $wgOut->setPagetitle( wfMsg( "actioncomplete" ) );
                $wgOut->setRobotpolicy( "noindex,nofollow" );
                $wgOut->addHTML( "<h2>" . $newcomment . "</h2>\n<hr>\n" );
-               $this->updateArticle( $s->old_text, $newcomment, 1, $this->mTitle->userIsWatching() );
+               $this->updateArticle( $s->old_text, $newcomment, 1, $this->mTitle->userIsWatching(), "", $bot );
 
                global $wgEnablePersistentLC;
                if ( $wgEnablePersistentLC ) {
                        wfQuery("DELETE FROM linkscc WHERE lcc_pageid='{$pid}'", DB_WRITE);
                }
-       
+               
+                       
                $wgOut->returnToMain( false );
        }
        
@@ -1061,6 +1079,7 @@ class Article {
        /* private */ function editUpdates( $text )
        {
                global $wgDeferredUpdateList, $wgDBname, $wgMemc;
+               global $wgMessageCache;
 
                wfSeedRandom();
                if ( 0 == mt_rand( 0, 999 ) ) {
@@ -1070,6 +1089,8 @@ class Article {
                }
                $id = $this->getID();
                $title = $this->mTitle->getPrefixedDBkey();
+               $shortTitle = $this->mTitle->getDBkey();
+               
                $adj = $this->mCountAdjustment;
 
                if ( 0 != $id ) {
@@ -1080,24 +1101,11 @@ class Article {
                        $u = new SearchUpdate( $id, $title, $text );
                        array_push( $wgDeferredUpdateList, $u );
 
-                       $u = new UserTalkUpdate( 1, $this->mTitle->getNamespace(),
-                         $this->mTitle->getDBkey() );
+                       $u = new UserTalkUpdate( 1, $this->mTitle->getNamespace(), $shortTitle );
                        array_push( $wgDeferredUpdateList, $u );
 
                        if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
-                               $messageCache = $wgMemc->get( "$wgDBname:messages" );
-
-                               # If another thread is loading, poll
-                               for ( $i=0; $i<70 && $messageCache == 'loading'; $i++ ) {
-                                       sleep(1);
-                                       $messageCache = $wgMemc->get( "$wgDBname:messages" );
-                               }
-                               
-                               if ( !$messageCache || $messageCache == 'loading' ) {
-                                       $messageCache = wfLoadAllMessages();
-                               }
-                               $messageCache[$this->mTitle->getDBkey()] = $text;
-                               $wgMemc->set( "$wgDBname:messages", $messageCache, 86400 );
+                               $wgMessageCache->replace( $shortTitle, $text );
                        }
                }
        }
index e5ae725..93e1e2b 100644 (file)
@@ -68,6 +68,7 @@ $wgShowIPinHeader     = true; # For non-logged in users
 # Translation using MediaWiki: namespace
 # Not recommended unless memcached is installed
 $wgUseDatabaseMessages = false;
+$wgMsgCacheExpiry      = 86400;
 
 $wgExtraSubtitle       = "";
 $wgSiteSupportPage     = "";
index 0239a43..a3b098c 100644 (file)
@@ -213,85 +213,24 @@ function wfMsgNoDB( $key ) {
 
 # Really get a message
 function wfMsgReal( $key, $args, $useDB ) {
-       global $wgLang, $wgReplacementKeys, $wgMemc, $wgDBname;
-       global $wgUseDatabaseMessages, $wgUseMemCached, $wgOut;
-       global $wgAllMessagesEn, $wgLanguageCode;
+       global $wgReplacementKeys, $wgMessageCache, $wgLang;
 
        $fname = "wfMsg";
        wfProfileIn( $fname );
-       
-       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 ) {
+       if ( $wgMessageCache ) {
+               $message = $wgMessageCache->get( $key, $useDB );
+       } elseif ( $wgLang ) {
                $message = $wgLang->getMessage( $key );
+       } else {
+               wfDebug( "No language object when getting $key\n" );
+               $message = "&lt;$key&gt;";
        }
 
-       if ( !$message && $wgUseMemCached ) {
-               # Try memcached
-               if ( !$messageCache ) {
-                       $messageCache = $wgMemc->get( $memcKey );
-               }
-               
-               # 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];
-               } elseif ( $messageCache == "loading" ) {
-                       $messageCache = 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 ) ) {
-                               $obj = wfFetchObject( $res );
-                               $message = $obj->cur_text;
-                               wfFreeResult( $res );
-                       }
-               }
-       }
-
-       # 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 ) ) {
                $message = str_replace( $wgReplacementKeys, $args, $message );
        }
        wfProfileOut( $fname );
-       if ( !$message ) {
-               # Failed, message does not exist
-               return "&lt;$key&gt;";
-       }
        return $message;
 }
 
@@ -702,20 +641,6 @@ function wfEscapeWikiText( $text )
        return $text;
 }
 
-# Loads the entire MediaWiki namespace, returns 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;
-}
-
 function wfQuotedPrintable( $string, $charset = "" ) 
 {
        # Probably incomplete; see RFC 2045
index 3831ca0..a14de1e 100644 (file)
@@ -31,7 +31,9 @@ class Namespace {
 
        function isMovable( $index )
        {
-               if ( $index < NS_MAIN || $index > NS_WP_TALK ) { return false; }
+               if ( $index < NS_MAIN || $index == NS_IMAGE ) { 
+                       return false; 
+               }
                return true;
        }
 
index 3079dc5..5f12702 100644 (file)
@@ -22,8 +22,6 @@ wfProfileIn( $fname );
 global $wgUseDynamicDates;
 wfProfileIn( "$fname-includes" );
 
-# Only files which are used on every invocation should be included here
-# Otherwise, include them conditionally [TS]
 include_once( "GlobalFunctions.php" );
 include_once( "Namespace.php" );
 include_once( "Skin.php" );
@@ -37,12 +35,15 @@ include_once( "MemCachedClient.inc.php" );
 include_once( "Block.php" );
 include_once( "SearchEngine.php" );
 include_once( "DifferenceEngine.php" );
+include_once( "MessageCache.php" );
 
 wfProfileOut( "$fname-includes" );
 wfProfileIn( "$fname-memcached" );
 global $wgUser, $wgLang, $wgOut, $wgTitle;
 global $wgArticle, $wgDeferredUpdateList, $wgLinkCache;
 global $wgMemc, $wgMagicWords, $wgMwRedir, $wgDebugLogFile;
+global $wgMessageCache, $wgUseMemCached, $wgUseDatabaseMessages;
+global $wgMsgCacheExpiry, $wgDBname;
 
 class MemCachedClientforWiki extends MemCachedClient {
        function _debug( $text ) {
@@ -68,6 +69,8 @@ wfProfileIn( "$fname-misc" );
 
 include_once( "Language.php" );
 
+$wgMessageCache = new MessageCache( $wgUseMemCached, $wgUseDatabaseMessages, $wgMsgCacheExpiry, $wgDBname );
+
 $wgOut = new OutputPage();
 wfDebug( "\n\n" );
 
index aa1733c..0ea4a5d 100644 (file)
@@ -101,7 +101,7 @@ class MovePageForm {
        {
                global $wgOut, $wgUser, $wgLang;
                global $wpNewTitle, $wpOldTitle, $wpMovetalk, $target;
-               global $wgDeferredUpdateList;
+               global $wgDeferredUpdateList, $wgMessageCache;
                $fname = "MovePageForm::doSubmit";
 
                $this->ot = Title::newFromText( $wpOldTitle );
@@ -134,7 +134,8 @@ class MovePageForm {
                     ( ! Namespace::isMovable( $nns ) ) ||
                         ( "" == $this->ndt ) ||
                         ( "" != $this->nt->getInterwiki() ) ||
-                        ( !$this->nt->userCanEdit() ) ) {
+                        ( !$this->nt->userCanEdit() ) || 
+                        ( $this->ons == NS_MEDIAWIKI && $wgMessageCache->isCacheable( $this->odt ) ) ) {
                        $this->showForm( wfMsg( "badarticleerror" ) );
                        return;
                }