MediaWiki
REL1_19
|
00001 <?php 00002 00007 class DBError extends MWException { 00008 00012 public $db; 00013 00019 function __construct( DatabaseBase &$db, $error ) { 00020 $this->db = $db; 00021 parent::__construct( $error ); 00022 } 00023 00028 protected function getContentMessage( $html ) { 00029 if ( $html ) { 00030 return nl2br( htmlspecialchars( $this->getMessage() ) ); 00031 } else { 00032 return $this->getMessage(); 00033 } 00034 } 00035 00039 function getText() { 00040 global $wgShowDBErrorBacktrace; 00041 00042 $s = $this->getContentMessage( false ) . "\n"; 00043 00044 if ( $wgShowDBErrorBacktrace ) { 00045 $s .= "Backtrace:\n" . $this->getTraceAsString() . "\n"; 00046 } 00047 00048 return $s; 00049 } 00050 00054 function getHTML() { 00055 global $wgShowDBErrorBacktrace; 00056 00057 $s = $this->getContentMessage( true ); 00058 00059 if ( $wgShowDBErrorBacktrace ) { 00060 $s .= '<p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ); 00061 } 00062 00063 return $s; 00064 } 00065 } 00066 00070 class DBConnectionError extends DBError { 00071 public $error; 00072 00073 function __construct( DatabaseBase &$db, $error = 'unknown error' ) { 00074 $msg = 'DB connection error'; 00075 00076 if ( trim( $error ) != '' ) { 00077 $msg .= ": $error"; 00078 } 00079 00080 $this->error = $error; 00081 00082 parent::__construct( $db, $msg ); 00083 } 00084 00088 function useOutputPage() { 00089 // Not likely to work 00090 return false; 00091 } 00092 00098 function msg( $key, $fallback /*[, params...] */ ) { 00099 global $wgLang; 00100 00101 $args = array_slice( func_get_args(), 2 ); 00102 00103 if ( $this->useMessageCache() ) { 00104 $message = $wgLang->getMessage( $key ); 00105 } else { 00106 $message = $fallback; 00107 } 00108 return wfMsgReplaceArgs( $message, $args ); 00109 } 00110 00114 function getLogMessage() { 00115 # Don't send to the exception log 00116 return false; 00117 } 00118 00122 function getPageTitle() { 00123 global $wgSitename; 00124 return htmlspecialchars( $this->msg( 'dberr-header', "$wgSitename has a problem" ) ); 00125 } 00126 00130 function getHTML() { 00131 global $wgShowDBErrorBacktrace; 00132 00133 $sorry = htmlspecialchars( $this->msg( 'dberr-problems', 'Sorry! This site is experiencing technical difficulties.' ) ); 00134 $again = htmlspecialchars( $this->msg( 'dberr-again', 'Try waiting a few minutes and reloading.' ) ); 00135 $info = htmlspecialchars( $this->msg( 'dberr-info', '(Can\'t contact the database server: $1)' ) ); 00136 00137 # No database access 00138 MessageCache::singleton()->disable(); 00139 00140 if ( trim( $this->error ) == '' ) { 00141 $this->error = $this->db->getProperty( 'mServer' ); 00142 } 00143 00144 $this->error = Html::element( 'span', array( 'dir' => 'ltr' ), $this->error ); 00145 00146 $noconnect = "<h1>$sorry</h1><p>$again</p><p><small>$info</small></p>"; 00147 $text = str_replace( '$1', $this->error, $noconnect ); 00148 00149 if ( $wgShowDBErrorBacktrace ) { 00150 $text .= '<p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ); 00151 } 00152 00153 $extra = $this->searchForm(); 00154 00155 return "$text<hr />$extra"; 00156 } 00157 00158 public function reportHTML(){ 00159 global $wgUseFileCache; 00160 00161 # Check whether we can serve a file-cached copy of the page with the error underneath 00162 if ( $wgUseFileCache ) { 00163 try { 00164 $cache = $this->fileCachedPage(); 00165 # Cached version on file system? 00166 if ( $cache !== null ) { 00167 # Hack: extend the body for error messages 00168 $cache = str_replace( array( '</html>', '</body>' ), '', $cache ); 00169 # Add cache notice... 00170 $cache .= '<div style="color:red;font-size:150%;font-weight:bold;">'. 00171 htmlspecialchars( $this->msg( 'dberr-cachederror', 00172 'This is a cached copy of the requested page, and may not be up to date. ' ) ) . 00173 '</div>'; 00174 00175 # Output cached page with notices on bottom and re-close body 00176 echo "{$cache}<hr />{$this->getHTML()}</body></html>"; 00177 return; 00178 } 00179 } catch ( MWException $e ) { 00180 // Do nothing, just use the default page 00181 } 00182 } 00183 00184 # We can't, cough and die in the usual fashion 00185 parent::reportHTML(); 00186 } 00187 00191 function searchForm() { 00192 global $wgSitename, $wgServer, $wgRequest; 00193 00194 $usegoogle = htmlspecialchars( $this->msg( 'dberr-usegoogle', 'You can try searching via Google in the meantime.' ) ); 00195 $outofdate = htmlspecialchars( $this->msg( 'dberr-outofdate', 'Note that their indexes of our content may be out of date.' ) ); 00196 $googlesearch = htmlspecialchars( $this->msg( 'searchbutton', 'Search' ) ); 00197 00198 $search = htmlspecialchars( $wgRequest->getVal( 'search' ) ); 00199 00200 $server = htmlspecialchars( $wgServer ); 00201 $sitename = htmlspecialchars( $wgSitename ); 00202 00203 $trygoogle = <<<EOT 00204 <div style="margin: 1.5em">$usegoogle<br /> 00205 <small>$outofdate</small></div> 00206 <!-- SiteSearch Google --> 00207 <form method="get" action="//www.google.com/search" id="googlesearch"> 00208 <input type="hidden" name="domains" value="$server" /> 00209 <input type="hidden" name="num" value="50" /> 00210 <input type="hidden" name="ie" value="UTF-8" /> 00211 <input type="hidden" name="oe" value="UTF-8" /> 00212 00213 <input type="text" name="q" size="31" maxlength="255" value="$search" /> 00214 <input type="submit" name="btnG" value="$googlesearch" /> 00215 <div> 00216 <input type="radio" name="sitesearch" id="gwiki" value="$server" checked="checked" /><label for="gwiki">$sitename</label> 00217 <input type="radio" name="sitesearch" id="gWWW" value="" /><label for="gWWW">WWW</label> 00218 </div> 00219 </form> 00220 <!-- SiteSearch Google --> 00221 EOT; 00222 return $trygoogle; 00223 } 00224 00228 private function fileCachedPage() { 00229 global $wgTitle, $wgOut, $wgRequest; 00230 00231 if ( $wgOut->isDisabled() ) { 00232 return ''; // Done already? 00233 } 00234 00235 if ( $wgTitle ) { // use $wgTitle if we managed to set it 00236 $t = $wgTitle->getPrefixedDBkey(); 00237 } else { 00238 # Fallback to the raw title URL param. We can't use the Title 00239 # class is it may hit the interwiki table and give a DB error. 00240 # We may get a cache miss due to not sanitizing the title though. 00241 $t = str_replace( ' ', '_', $wgRequest->getVal( 'title' ) ); 00242 if ( $t == '' ) { // fallback to main page 00243 $t = Title::newFromText( 00244 $this->msg( 'mainpage', 'Main Page' ) )->getPrefixedDBkey(); 00245 } 00246 } 00247 00248 $cache = HTMLFileCache::newFromTitle( $t, 'view' ); 00249 if ( $cache->isCached() ) { 00250 return $cache->fetchText(); 00251 } else { 00252 return ''; 00253 } 00254 } 00255 } 00256 00260 class DBQueryError extends DBError { 00261 public $error, $errno, $sql, $fname; 00262 00270 function __construct( DatabaseBase &$db, $error, $errno, $sql, $fname ) { 00271 $message = "A database error has occurred. Did you forget to run maintenance/update.php after upgrading? See: https://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script\n" . 00272 "Query: $sql\n" . 00273 "Function: $fname\n" . 00274 "Error: $errno $error\n"; 00275 parent::__construct( $db, $message ); 00276 00277 $this->error = $error; 00278 $this->errno = $errno; 00279 $this->sql = $sql; 00280 $this->fname = $fname; 00281 } 00282 00287 function getContentMessage( $html ) { 00288 if ( $this->useMessageCache() ) { 00289 if ( $html ) { 00290 $msg = 'dberrortext'; 00291 $sql = htmlspecialchars( $this->getSQL() ); 00292 $fname = htmlspecialchars( $this->fname ); 00293 $error = htmlspecialchars( $this->error ); 00294 } else { 00295 $msg = 'dberrortextcl'; 00296 $sql = $this->getSQL(); 00297 $fname = $this->fname; 00298 $error = $this->error; 00299 } 00300 return wfMsg( $msg, $sql, $fname, $this->errno, $error ); 00301 } else { 00302 return parent::getContentMessage( $html ); 00303 } 00304 } 00305 00309 function getSQL() { 00310 global $wgShowSQLErrors; 00311 00312 if ( !$wgShowSQLErrors ) { 00313 return $this->msg( 'sqlhidden', 'SQL hidden' ); 00314 } else { 00315 return $this->sql; 00316 } 00317 } 00318 00322 function getLogMessage() { 00323 # Don't send to the exception log 00324 return false; 00325 } 00326 00330 function getPageTitle() { 00331 return $this->msg( 'databaseerror', 'Database error' ); 00332 } 00333 } 00334 00338 class DBUnexpectedError extends DBError {}