Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

MessageCache.php

Go to the documentation of this file.
00001 <?php 00002 00003 # Message cache 00004 # Performs various useful MediaWiki namespace-related functions 00005 00006 define( "MSG_LOAD_TIMEOUT", 60); 00007 define( "MSG_LOCK_TIMEOUT", 10); 00008 define( "MSG_WAIT_TIMEOUT", 10); 00009 00010 class MessageCache 00011 { 00012 var $mCache, $mUseCache, $mDisable, $mExpiry; 00013 var $mMemcKey, $mKeys, $mParserOptions, $mParser; 00014 var $mExtensionMessages; 00015 00016 var $mInitialised = false; 00017 00018 function initialise( &$memCached, $useDB, $expiry, $memcPrefix ) { 00019 $this->mUseCache = !is_null( $memCached ); 00020 $this->mMemc = &$memCached; 00021 $this->mDisable = !$useDB; 00022 $this->mExpiry = $expiry; 00023 $this->mDisableTransform = false; 00024 $this->mMemcKey = "$memcPrefix:messages"; 00025 $this->mKeys = false; # initialised on demand 00026 $this->mInitialised = true; 00027 $this->mParserOptions = ParserOptions::newFromUser( $u=NULL ); 00028 $this->mParser = new Parser; 00029 00030 $this->load(); 00031 } 00032 00033 # Loads messages either from memcached or the database, if not disabled 00034 # On error, quietly switches to a fallback mode 00035 # Returns false for a reportable error, true otherwise 00036 function load() { 00037 global $wgAllMessagesEn; 00038 00039 if ( $this->mDisable ) { 00040 return true; 00041 } 00042 00043 $success = true; 00044 00045 if ( $this->mUseCache ) { 00046 $this->mCache = $this->mMemc->get( $this->mMemcKey ); 00047 00048 # If there's nothing in memcached, load all the messages from the database 00049 if ( !$this->mCache ) { 00050 $this->lock(); 00051 # Other threads don't need to load the messages if another thread is doing it. 00052 $this->mMemc->set( $this->mMemcKey, "loading", MSG_LOAD_TIMEOUT ); 00053 $this->loadFromDB(); 00054 # Save in memcached 00055 if ( !$this->mMemc->set( $this->mMemcKey, $this->mCache, $this->mExpiry ) ) { 00056 # Hack for slabs reassignment problem 00057 $this->mMemc->set( $this->mMemcKey, "error" ); 00058 wfDebug( "MemCached set error in MessageCache: restart memcached server!\n" ); 00059 } 00060 $this->unlock(); 00061 } 00062 00063 if ( !is_array( $this->mCache ) ) { 00064 # If it is 'loading' or 'error', switch to individual message mode, otherwise disable 00065 if ( $this->mCache == "loading" ) { 00066 $this->mUseCache = false; 00067 } elseif ( $this->mCache == "error" ) { 00068 $this->mUseCache = false; 00069 $success = false; 00070 } else { 00071 $this->mDisable = true; 00072 $success = false; 00073 } 00074 $this->mCache = false; 00075 } 00076 } 00077 return $success; 00078 } 00079 00080 # Loads all cacheable messages from the database 00081 function loadFromDB() 00082 { 00083 $fname = "MessageCache::loadFromDB"; 00084 $sql = "SELECT cur_title,cur_text FROM cur WHERE cur_is_redirect=0 AND cur_namespace=" . NS_MEDIAWIKI; 00085 $res = wfQuery( $sql, DB_READ, $fname ); 00086 00087 $this->mCache = array(); 00088 for ( $row = wfFetchObject( $res ); $row; $row = wfFetchObject( $res ) ) { 00089 $this->mCache[$row->cur_title] = $row->cur_text; 00090 } 00091 00092 wfFreeResult( $res ); 00093 } 00094 00095 # Not really needed anymore 00096 function getKeys() { 00097 global $wgAllMessagesEn, $wgLang; 00098 if ( !$this->mKeys ) { 00099 $this->mKeys = array(); 00100 foreach ( $wgAllMessagesEn as $key => $value ) { 00101 array_push( $this->mKeys, $wgLang->ucfirst( $key ) ); 00102 } 00103 } 00104 return $this->mKeys; 00105 } 00106 00107 # Obsolete 00108 function isCacheable( $key ) { 00109 return true; 00110 /* 00111 global $wgAllMessagesEn, $wgLang; 00112 return array_key_exists( $wgLang->lcfirst( $key ), $wgAllMessagesEn ) || 00113 array_key_exists( $key, $wgAllMessagesEn ); 00114 */ 00115 } 00116 00117 function replace( $title, $text ) { 00118 $this->lock(); 00119 $this->load(); 00120 if ( is_array( $this->mCache ) ) { 00121 $this->mCache[$title] = $text; 00122 $this->mMemc->set( $this->mMemcKey, $this->mCache, $this->mExpiry ); 00123 } 00124 $this->unlock(); 00125 } 00126 00127 # Returns success 00128 # Represents a write lock on the messages key 00129 function lock() { 00130 if ( !$this->mUseCache ) { 00131 return true; 00132 } 00133 00134 $lockKey = $this->mMemcKey . "lock"; 00135 for ($i=0; $i < MSG_WAIT_TIMEOUT && !$this->mMemc->add( $lockKey, 1, MSG_LOCK_TIMEOUT ); $i++ ) { 00136 sleep(1); 00137 } 00138 00139 return $i >= MSG_WAIT_TIMEOUT; 00140 } 00141 00142 function unlock() { 00143 if ( !$this->mUseCache ) { 00144 return; 00145 } 00146 00147 $lockKey = $this->mMemcKey . "lock"; 00148 $this->mMemc->delete( $lockKey ); 00149 } 00150 00151 function get( $key, $useDB ) { 00152 global $wgLang, $wgLanguageCode; 00153 00154 # If uninitialised, someone is trying to call this halfway through Setup.php 00155 if ( !$this->mInitialised ) { 00156 return "&lt;$key&gt;"; 00157 } 00158 00159 $message = false; 00160 if ( !$this->mDisable ) { 00161 $title = $wgLang->ucfirst( $key ); 00162 00163 00164 # Try the cache 00165 if ( $this->mUseCache && $this->mCache && array_key_exists( $title, $this->mCache ) ) { 00166 $message = $this->mCache[$title]; 00167 } 00168 00169 # If it wasn't in the cache, load each message from the DB individually 00170 if ( !$message && $useDB) { 00171 $result = wfGetArray( "cur", array("cur_text"), 00172 array( "cur_namespace" => NS_MEDIAWIKI, "cur_title" => $title ), 00173 "MessageCache::get" ); 00174 if ( $result ) { 00175 $message = $result->cur_text; 00176 } 00177 } 00178 } 00179 # Try the extension array 00180 if ( !$message ) { 00181 $message = @$this->mExtensionMessages[$key]; 00182 } 00183 00184 # Try the array in $wgLang 00185 if ( !$message ) { 00186 $message = $wgLang->getMessage( $key ); 00187 } 00188 00189 # Try the English array 00190 if ( !$message && $wgLanguageCode != "en" ) { 00191 $message = Language::getMessage( $key ); 00192 } 00193 00194 # Final fallback 00195 if ( !$message ) { 00196 $message = "&lt;$key&gt;"; 00197 } 00198 00199 # Replace brace tags 00200 $message = $this->transform( $message ); 00201 return $message; 00202 } 00203 00204 function transform( $message ) { 00205 if( !$this->mDisableTransform ) { 00206 if ( strstr( $message, "{{" ) !== false ) { 00207 $message = $this->mParser->transformMsg( $message, $this->mParserOptions ); 00208 } 00209 } 00210 return $message; 00211 } 00212 00213 function disable() { $this->mDisable = true; } 00214 function enable() { $this->mDisable = false; } 00215 function disableTransform() { $this->mDisableTransform = true; } 00216 00217 function addMessage( $key, $value ) { 00218 $this->mExtensionMessages[$key] = $value; 00219 } 00220 00221 function addMessages( $messages ) { 00222 foreach ( $messages as $key => $value ) { 00223 $this->mExtensionMessages[$key] = $value; 00224 } 00225 } 00226 } 00227 ?>

Generated on Tue Jun 29 23:40:05 2004 for Mediawiki by doxygen 1.3.7