From 036ff960cefa2e05749b4ecc34043f2a2543dafe Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Sun, 14 Dec 2003 14:29:35 +0000 Subject: [PATCH] Improvements in MediaWiki namespace handling, enhanced rollback --- includes/Article.php | 56 +++++++++++++---------- includes/DefaultSettings.php | 1 + includes/GlobalFunctions.php | 89 +++--------------------------------- includes/Namespace.php | 4 +- includes/Setup.php | 7 ++- includes/SpecialMovepage.php | 5 +- 6 files changed, 51 insertions(+), 111 deletions(-) diff --git a/includes/Article.php b/includes/Article.php index 0c3afaf912..44d6a8d979 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -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( "

" . $newcomment . "

\n
\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 ); } } } diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index e5ae7254bb..93e1e2b071 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -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 = ""; diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 0239a43946..a3b098c10a 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -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 = "<$key>"; } - 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 "<$key>"; - } 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 diff --git a/includes/Namespace.php b/includes/Namespace.php index 3831ca0832..a14de1e9d0 100644 --- a/includes/Namespace.php +++ b/includes/Namespace.php @@ -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; } diff --git a/includes/Setup.php b/includes/Setup.php index 3079dc5e88..5f127027d2 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -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" ); diff --git a/includes/SpecialMovepage.php b/includes/SpecialMovepage.php index aa1733cbb6..0ea4a5d4f5 100644 --- a/includes/SpecialMovepage.php +++ b/includes/SpecialMovepage.php @@ -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; } -- 2.20.1