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

OutputPage.php

Go to the documentation of this file.
00001 <?php 00002 # See design.doc 00003 00004 if($wgUseTeX) require_once( "Math.php" ); 00005 00006 class OutputPage { 00007 var $mHeaders, $mCookies, $mMetatags, $mKeywords; 00008 var $mLinktags, $mPagetitle, $mBodytext, $mDebugtext; 00009 var $mHTMLtitle, $mRobotpolicy, $mIsarticle, $mPrintable; 00010 var $mSubtitle, $mRedirect; 00011 var $mLastModified, $mCategoryLinks; 00012 var $mScripts; 00013 00014 var $mSuppressQuickbar; 00015 var $mOnloadHandler; 00016 var $mDoNothing; 00017 var $mContainsOldMagic, $mContainsNewMagic; 00018 var $mIsArticleRelated; 00019 var $mParserOptions; 00020 var $mShowFeedLinks = false; 00021 var $mEnableClientCache = true; 00022 00023 function OutputPage() 00024 { 00025 $this->mHeaders = $this->mCookies = $this->mMetatags = 00026 $this->mKeywords = $this->mLinktags = array(); 00027 $this->mHTMLtitle = $this->mPagetitle = $this->mBodytext = 00028 $this->mRedirect = $this->mLastModified = 00029 $this->mSubtitle = $this->mDebugtext = $this->mRobotpolicy = 00030 $this->mOnloadHandler = ""; 00031 $this->mIsArticleRelated = $this->mIsarticle = $this->mPrintable = true; 00032 $this->mSuppressQuickbar = $this->mPrintable = false; 00033 $this->mLanguageLinks = array(); 00034 $this->mCategoryLinks = array() ; 00035 $this->mDoNothing = false; 00036 $this->mContainsOldMagic = $this->mContainsNewMagic = 0; 00037 $this->mParserOptions = ParserOptions::newFromUser( $temp = NULL ); 00038 $this->mSquidMaxage = 0; 00039 $this->mScripts = ""; 00040 } 00041 00042 function addHeader( $name, $val ) { array_push( $this->mHeaders, "$name: $val" ) ; } 00043 function addCookie( $name, $val ) { array_push( $this->mCookies, array( $name, $val ) ); } 00044 function redirect( $url, $responsecode = '302' ) { $this->mRedirect = $url; $this->mRedirectCode = $responsecode; } 00045 00046 # To add an http-equiv meta tag, precede the name with "http:" 00047 function addMeta( $name, $val ) { array_push( $this->mMetatags, array( $name, $val ) ); } 00048 function addKeyword( $text ) { array_push( $this->mKeywords, $text ); } 00049 function addScript( $script ) { $this->mScripts .= $script; } 00050 function getScript() { return $this->mScripts; } 00051 00052 function addLink( $linkarr ) { 00053 # $linkarr should be an associative array of attributes. We'll escape on output. 00054 array_push( $this->mLinktags, $linkarr ); 00055 } 00056 00057 function addMetadataLink( $linkarr ) { 00058 # note: buggy CC software only reads first "meta" link 00059 static $haveMeta = false; 00060 $linkarr["rel"] = ($haveMeta) ? "alternate meta" : "meta"; 00061 $this->addLink( $linkarr ); 00062 $haveMeta = true; 00063 } 00064 00065 # checkLastModified tells the client to use the client-cached page if 00066 # possible. If sucessful, the OutputPage is disabled so that 00067 # any future call to OutputPage->output() have no effect. The method 00068 # returns true iff cache-ok headers was sent. 00069 function checkLastModified ( $timestamp ) 00070 { 00071 global $wgLang, $wgCachePages, $wgUser; 00072 if( !$wgCachePages ) { 00073 wfDebug( "CACHE DISABLED\n", false ); 00074 return; 00075 } 00076 if( preg_match( '/MSIE ([1-4]|5\.0)/', $_SERVER["HTTP_USER_AGENT"] ) ) { 00077 # IE 5.0 has probs with our caching 00078 wfDebug( "-- bad client, not caching\n", false ); 00079 return; 00080 } 00081 if( $wgUser->getOption( "nocache" ) ) { 00082 wfDebug( "USER DISABLED CACHE\n", false ); 00083 return; 00084 } 00085 00086 $lastmod = gmdate( "D, j M Y H:i:s", wfTimestamp2Unix( max( $timestamp, $wgUser->mTouched ) ) ) . " GMT"; 00087 00088 if( !empty( $_SERVER["HTTP_IF_MODIFIED_SINCE"] ) ) { 00089 # IE sends sizes after the date like this: 00090 # Wed, 20 Aug 2003 06:51:19 GMT; length=5202 00091 # this breaks strtotime(). 00092 $modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] ); 00093 $ismodsince = wfUnix2Timestamp( strtotime( $modsince ) ); 00094 wfDebug( "-- client send If-Modified-Since: " . $modsince . "\n", false ); 00095 wfDebug( "-- we might send Last-Modified : $lastmod\n", false ); 00096 00097 if( ($ismodsince >= $timestamp ) and $wgUser->validateCache( $ismodsince ) ) { 00098 # Make sure you're in a place you can leave when you call us! 00099 header( "HTTP/1.0 304 Not Modified" ); 00100 $this->mLastModified = $lastmod; 00101 $this->sendCacheControl(); 00102 wfDebug( "CACHED client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false ); 00103 $this->disable(); 00104 return true; 00105 } else { 00106 wfDebug( "READY client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false ); 00107 $this->mLastModified = $lastmod; 00108 } 00109 } else { 00110 wfDebug( "We're confused.\n", false ); 00111 $this->mLastModified = $lastmod; 00112 } 00113 } 00114 00115 function getPageTitleActionText () { 00116 global $action; 00117 switch($action) { 00118 case 'edit': 00119 return wfMsg('edit'); 00120 case 'history': 00121 return wfMsg('history_short'); 00122 case 'protect': 00123 return wfMsg('unprotect'); 00124 case 'unprotect': 00125 return wfMsg('unprotect'); 00126 case 'delete': 00127 return wfMsg('delete'); 00128 case 'watch': 00129 return wfMsg('watch'); 00130 case 'unwatch': 00131 return wfMsg('unwatch'); 00132 case 'submit': 00133 return wfMsg('preview'); 00134 default: 00135 return ''; 00136 } 00137 } 00138 function setRobotpolicy( $str ) { $this->mRobotpolicy = $str; } 00139 function setHTMLTitle( $name ) {$this->mHTMLtitle = $name; } 00140 function setPageTitle( $name ) { 00141 global $action; 00142 $this->mPagetitle = $name; 00143 if(!empty($action)) { 00144 $taction = $this->getPageTitleActionText(); 00145 if( !empty( $taction ) ) { 00146 $name .= " - $taction"; 00147 } 00148 } 00149 $this->setHTMLTitle( $name . " - " . wfMsg( "wikititlesuffix" ) ); 00150 } 00151 function getHTMLTitle() { return $this->mHTMLtitle; } 00152 function getPageTitle() { return $this->mPagetitle; } 00153 function setSubtitle( $str ) { $this->mSubtitle = $str; } 00154 function getSubtitle() { return $this->mSubtitle; } 00155 function isArticle() { return $this->mIsarticle; } 00156 function setPrintable() { $this->mPrintable = true; } 00157 function isPrintable() { return $this->mPrintable; } 00158 function setSyndicated( $show = true ) { $this->mShowFeedLinks = $show; } 00159 function isSyndicated() { return $this->mShowFeedLinks; } 00160 function setOnloadHandler( $js ) { $this->mOnloadHandler = $js; } 00161 function getOnloadHandler() { return $this->mOnloadHandler; } 00162 function disable() { $this->mDoNothing = true; } 00163 00164 function setArticleRelated( $v ) 00165 { 00166 $this->mIsArticleRelated = $v; 00167 if ( !$v ) { 00168 $this->mIsarticle = false; 00169 } 00170 } 00171 function setArticleFlag( $v ) { 00172 $this->mIsarticle = $v; 00173 if ( $v ) { 00174 $this->mIsArticleRelated = $v; 00175 } 00176 } 00177 00178 function isArticleRelated() 00179 { 00180 return $this->mIsArticleRelated; 00181 } 00182 00183 function getLanguageLinks() { 00184 return $this->mLanguageLinks; 00185 } 00186 function addLanguageLinks($newLinkArray) { 00187 $this->mLanguageLinks += $newLinkArray; 00188 } 00189 function setLanguageLinks($newLinkArray) { 00190 $this->mLanguageLinks = $newLinkArray; 00191 } 00192 function getCategoryLinks() { 00193 return $this->mCategoryLinks; 00194 } 00195 function addCategoryLinks($newLinkArray) { 00196 $this->mCategoryLinks += $newLinkArray; 00197 } 00198 function setCategoryLinks($newLinkArray) { 00199 $this->mCategoryLinks += $newLinkArray; 00200 } 00201 00202 function suppressQuickbar() { $this->mSuppressQuickbar = true; } 00203 function isQuickbarSuppressed() { return $this->mSuppressQuickbar; } 00204 00205 function addHTML( $text ) { $this->mBodytext .= $text; } 00206 function debug( $text ) { $this->mDebugtext .= $text; } 00207 00208 function setParserOptions( $options ) 00209 { 00210 return wfSetVar( $this->mParserOptions, $options ); 00211 } 00212 00213 # First pass--just handle <nowiki> sections, pass the rest off 00214 # to doWikiPass2() which does all the real work. 00215 # 00216 # $cacheArticle - assume this text is the main text for the given article 00217 # 00218 function addWikiText( $text, $linestart = true, $cacheArticle = NULL ) 00219 { 00220 global $wgParser, $wgParserCache, $wgUser, $wgTitle; 00221 00222 $parserOutput = $wgParser->parse( $text, $wgTitle, $this->mParserOptions, $linestart ); 00223 if ( $cacheArticle ) { 00224 $wgParserCache->save( $parserOutput, $cacheArticle, $wgUser ); 00225 } 00226 00227 $this->mLanguageLinks += $parserOutput->getLanguageLinks(); 00228 $this->mCategoryLinks += $parserOutput->getCategoryLinks(); 00229 $this->addHTML( $parserOutput->getText() ); 00230 } 00231 00232 function tryParserCache( $article, $user ) { 00233 global $wgParserCache; 00234 $parserOutput = $wgParserCache->get( $article, $user ); 00235 if ( $parserOutput !== false ) { 00236 $this->mLanguageLinks += $parserOutput->getLanguageLinks(); 00237 $this->mCategoryLinks += $parserOutput->getCategoryLinks(); 00238 $this->addHTML( $parserOutput->getText() ); 00239 return true; 00240 } else { 00241 return false; 00242 } 00243 } 00244 00245 # Set the maximum cache time on the Squid in seconds 00246 function setSquidMaxage( $maxage ) { 00247 $this->mSquidMaxage = $maxage; 00248 } 00249 00250 # Use enableClientCache(false) to force it to send nocache headers 00251 function enableClientCache( $state ) { 00252 return wfSetVar( $this->mEnableClientCache, $state ); 00253 } 00254 00255 function sendCacheControl() { 00256 global $wgUseSquid, $wgUseESI; 00257 # FIXME: This header may cause trouble with some versions of Internet Explorer 00258 header( "Vary: Accept-Encoding, Cookie" ); 00259 if( $this->mEnableClientCache ) { 00260 if( $wgUseSquid && ! isset( $_COOKIE[ini_get( "session.name") ] ) && 00261 ! $this->isPrintable() && $this->mSquidMaxage != 0 ) 00262 { 00263 if ( $wgUseESI ) { 00264 # We'll purge the proxy cache explicitly, but require end user agents 00265 # to revalidate against the proxy on each visit. 00266 # Surrogate-Control controls our Squid, Cache-Control downstream caches 00267 wfDebug( "** proxy caching with ESI; {$this->mLastModified} **\n", false ); 00268 # start with a shorter timeout for initial testing 00269 # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"'); 00270 header( 'Surrogate-Control: max-age='.$wgSquidMaxage.'+'.$this->mSquidMaxage.', content="ESI/1.0"'); 00271 header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' ); 00272 } else { 00273 # We'll purge the proxy cache for anons explicitly, but require end user agents 00274 # to revalidate against the proxy on each visit. 00275 # IMPORTANT! The Squid needs to replace the Cache-Control header with 00276 # Cache-Control: s-maxage=0, must-revalidate, max-age=0 00277 wfDebug( "** local proxy caching; {$this->mLastModified} **\n", false ); 00278 # start with a shorter timeout for initial testing 00279 # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" ); 00280 header( 'Cache-Control: s-maxage='.$this->mSquidMaxage.', must-revalidate, max-age=0' ); 00281 } 00282 } else { 00283 # We do want clients to cache if they can, but they *must* check for updates 00284 # on revisiting the page. 00285 wfDebug( "** private caching; {$this->mLastModified} **\n", false ); 00286 header( "Expires: -1" ); 00287 header( "Cache-Control: private, must-revalidate, max-age=0" ); 00288 } 00289 if($this->mLastModified) header( "Last-modified: {$this->mLastModified}" ); 00290 } else { 00291 wfDebug( "** no caching **\n", false ); 00292 00293 # In general, the absence of a last modified header should be enough to prevent 00294 # the client from using its cache. We send a few other things just to make sure. 00295 header( "Expires: -1" ); 00296 header( "Cache-Control: no-cache, no-store, max-age=0, must-revalidate" ); 00297 header( "Pragma: no-cache" ); 00298 } 00299 } 00300 00301 # Finally, all the text has been munged and accumulated into 00302 # the object, let's actually output it: 00303 # 00304 function output() 00305 { 00306 global $wgUser, $wgLang, $wgDebugComments, $wgCookieExpiration; 00307 global $wgInputEncoding, $wgOutputEncoding, $wgLanguageCode; 00308 global $wgDebugRedirects, $wgMimeType; 00309 if( $this->mDoNothing ){ 00310 return; 00311 } 00312 $fname = "OutputPage::output"; 00313 wfProfileIn( $fname ); 00314 00315 $sk = $wgUser->getSkin(); 00316 00317 if ( "" != $this->mRedirect ) { 00318 if( substr( $this->mRedirect, 0, 4 ) != "http" ) { 00319 # Standards require redirect URLs to be absolute 00320 global $wgServer; 00321 $this->mRedirect = $wgServer . $this->mRedirect; 00322 } 00323 if( $this->mRedirectCode == '301') { 00324 if( !$wgDebugRedirects ) { 00325 header("HTTP/1.1 {$this->mRedirectCode} Moved Permanently"); 00326 } 00327 $this->mLastModified = gmdate( "D, j M Y H:i:s" ) . " GMT"; 00328 } 00329 00330 $this->sendCacheControl(); 00331 00332 if( $wgDebugRedirects ) { 00333 $url = htmlspecialchars( $this->mRedirect ); 00334 print "<html>\n<head>\n<title>Redirect</title>\n</head>\n<body>\n"; 00335 print "<p>Location: <a href=\"$url\">$url</a></p>\n"; 00336 print "</body>\n</html>\n"; 00337 } else { 00338 header( "Location: {$this->mRedirect}" ); 00339 } 00340 return; 00341 } 00342 00343 00344 $this->sendCacheControl(); 00345 00346 header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" ); 00347 header( "Content-language: {$wgLanguageCode}" ); 00348 00349 $exp = time() + $wgCookieExpiration; 00350 foreach( $this->mCookies as $name => $val ) { 00351 setcookie( $name, $val, $exp, "/" ); 00352 } 00353 00354 $sk->outputPage( $this ); 00355 # flush(); 00356 } 00357 00358 function out( $ins ) 00359 { 00360 global $wgInputEncoding, $wgOutputEncoding, $wgLang; 00361 if ( 0 == strcmp( $wgInputEncoding, $wgOutputEncoding ) ) { 00362 $outs = $ins; 00363 } else { 00364 $outs = $wgLang->iconv( $wgInputEncoding, $wgOutputEncoding, $ins ); 00365 if ( false === $outs ) { $outs = $ins; } 00366 } 00367 print $outs; 00368 } 00369 00370 function setEncodings() 00371 { 00372 global $wgInputEncoding, $wgOutputEncoding; 00373 global $wgUser, $wgLang; 00374 00375 $wgInputEncoding = strtolower( $wgInputEncoding ); 00376 00377 if( $wgUser->getOption( 'altencoding' ) ) { 00378 $wgLang->setAltEncoding(); 00379 return; 00380 } 00381 00382 if ( empty( $_SERVER['HTTP_ACCEPT_CHARSET'] ) ) { 00383 $wgOutputEncoding = strtolower( $wgOutputEncoding ); 00384 return; 00385 } 00386 00387 /* 00388 # This code is unused anyway! 00389 # Commenting out. --bv 2003-11-15 00390 00391 $a = explode( ",", $_SERVER['HTTP_ACCEPT_CHARSET'] ); 00392 $best = 0.0; 00393 $bestset = "*"; 00394 00395 foreach ( $a as $s ) { 00396 if ( preg_match( "/(.*);q=(.*)/", $s, $m ) ) { 00397 $set = $m[1]; 00398 $q = (float)($m[2]); 00399 } else { 00400 $set = $s; 00401 $q = 1.0; 00402 } 00403 if ( $q > $best ) { 00404 $bestset = $set; 00405 $best = $q; 00406 } 00407 } 00408 #if ( "*" == $bestset ) { $bestset = "iso-8859-1"; } 00409 if ( "*" == $bestset ) { $bestset = $wgOutputEncoding; } 00410 $wgOutputEncoding = strtolower( $bestset ); 00411 00412 # Disable for now 00413 # 00414 */ 00415 $wgOutputEncoding = $wgInputEncoding; 00416 } 00417 00418 # Returns a HTML comment with the elapsed time since request. 00419 # This method has no side effects. 00420 function reportTime() 00421 { 00422 global $wgRequestTime; 00423 00424 $now = wfTime(); 00425 list( $usec, $sec ) = explode( " ", $wgRequestTime ); 00426 $start = (float)$sec + (float)$usec; 00427 $elapsed = $now - $start; 00428 00429 # Use real server name if available, so we know which machine 00430 # in a server farm generated the current page. 00431 if ( function_exists( "posix_uname" ) ) { 00432 $uname = @posix_uname(); 00433 } else { 00434 $uname = false; 00435 } 00436 if( is_array( $uname ) && isset( $uname['nodename'] ) ) { 00437 $hostname = $uname['nodename']; 00438 } else { 00439 # This may be a virtual server. 00440 $hostname = $_SERVER['SERVER_NAME']; 00441 } 00442 $com = sprintf( "<!-- Served by %s in %01.2f secs. -->", 00443 $hostname, $elapsed ); 00444 return $com; 00445 } 00446 00447 # Note: these arguments are keys into wfMsg(), not text! 00448 # 00449 function errorpage( $title, $msg ) 00450 { 00451 global $wgTitle; 00452 00453 $this->mDebugtext .= "Original title: " . 00454 $wgTitle->getPrefixedText() . "\n"; 00455 $this->setPageTitle( wfMsg( $title ) ); 00456 $this->setHTMLTitle( wfMsg( "errorpagetitle" ) ); 00457 $this->setRobotpolicy( "noindex,nofollow" ); 00458 $this->setArticleRelated( false ); 00459 $this->enableClientCache( false ); 00460 00461 $this->mBodytext = ""; 00462 $this->addHTML( "<p>" . wfMsg( $msg ) . "</p>\n" ); 00463 $this->returnToMain( false ); 00464 00465 $this->output(); 00466 wfAbruptExit(); 00467 } 00468 00469 function sysopRequired() 00470 { 00471 global $wgUser; 00472 00473 $this->setPageTitle( wfMsg( "sysoptitle" ) ); 00474 $this->setHTMLTitle( wfMsg( "errorpagetitle" ) ); 00475 $this->setRobotpolicy( "noindex,nofollow" ); 00476 $this->setArticleRelated( false ); 00477 $this->mBodytext = ""; 00478 00479 $sk = $wgUser->getSkin(); 00480 $ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" ); 00481 $this->addHTML( wfMsg( "sysoptext", $ap ) ); 00482 $this->returnToMain(); 00483 } 00484 00485 function developerRequired() 00486 { 00487 global $wgUser; 00488 00489 $this->setPageTitle( wfMsg( "developertitle" ) ); 00490 $this->setHTMLTitle( wfMsg( "errorpagetitle" ) ); 00491 $this->setRobotpolicy( "noindex,nofollow" ); 00492 $this->setArticleRelated( false ); 00493 $this->mBodytext = ""; 00494 00495 $sk = $wgUser->getSkin(); 00496 $ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" ); 00497 $this->addHTML( wfMsg( "developertext", $ap ) ); 00498 $this->returnToMain(); 00499 } 00500 00501 function loginToUse() 00502 { 00503 global $wgUser, $wgTitle, $wgLang; 00504 00505 $this->setPageTitle( wfMsg( "loginreqtitle" ) ); 00506 $this->setHTMLTitle( wfMsg( "errorpagetitle" ) ); 00507 $this->setRobotpolicy( "noindex,nofollow" ); 00508 $this->setArticleFlag( false ); 00509 $this->mBodytext = ""; 00510 $this->addWikiText( wfMsg( "loginreqtext" ) ); 00511 00512 # We put a comment in the .html file so a Sysop can diagnose the page the 00513 # user can't see. 00514 $this->addHTML( "\n<!--" . 00515 $wgLang->getNsText( $wgTitle->getNamespace() ) . 00516 ":" . 00517 $wgTitle->getDBkey() . "-->" ); 00518 $this->returnToMain(); # Flip back to the main page after 10 seconds. 00519 } 00520 00521 function databaseError( $fname, $sql, $error, $errno ) 00522 { 00523 global $wgUser, $wgCommandLineMode; 00524 00525 $this->setPageTitle( wfMsgNoDB( "databaseerror" ) ); 00526 $this->setRobotpolicy( "noindex,nofollow" ); 00527 $this->setArticleRelated( false ); 00528 $this->enableClientCache( false ); 00529 00530 if ( $wgCommandLineMode ) { 00531 $msg = wfMsgNoDB( "dberrortextcl" ); 00532 } else { 00533 $msg = wfMsgNoDB( "dberrortext" ); 00534 } 00535 00536 $msg = str_replace( "$1", htmlspecialchars( $sql ), $msg ); 00537 $msg = str_replace( "$2", htmlspecialchars( $fname ), $msg ); 00538 $msg = str_replace( "$3", $errno, $msg ); 00539 $msg = str_replace( "$4", htmlspecialchars( $error ), $msg ); 00540 00541 if ( $wgCommandLineMode || !is_object( $wgUser )) { 00542 print "$msg\n"; 00543 wfAbruptExit(); 00544 } 00545 $sk = $wgUser->getSkin(); 00546 $shlink = $sk->makeKnownLink( wfMsgNoDB( "searchhelppage" ), 00547 wfMsgNoDB( "searchingwikipedia" ) ); 00548 $msg = str_replace( "$5", $shlink, $msg ); 00549 $this->mBodytext = $msg; 00550 $this->output(); 00551 wfAbruptExit(); 00552 } 00553 00554 function readOnlyPage( $source = null, $protected = false ) 00555 { 00556 global $wgUser, $wgReadOnlyFile; 00557 00558 $this->setRobotpolicy( "noindex,nofollow" ); 00559 $this->setArticleRelated( false ); 00560 00561 if( $protected ) { 00562 $this->setPageTitle( wfMsg( "viewsource" ) ); 00563 $this->addWikiText( wfMsg( "protectedtext" ) ); 00564 } else { 00565 $this->setPageTitle( wfMsg( "readonly" ) ); 00566 $reason = file_get_contents( $wgReadOnlyFile ); 00567 $this->addWikiText( wfMsg( "readonlytext", $reason ) ); 00568 } 00569 00570 if( is_string( $source ) ) { 00571 if( strcmp( $source, "" ) == 0 ) { 00572 $source = wfMsg( "noarticletext" ); 00573 } 00574 $rows = $wgUser->getOption( "rows" ); 00575 $cols = $wgUser->getOption( "cols" ); 00576 $text = "\n<textarea cols='$cols' rows='$rows' readonly='readonly'>" . 00577 htmlspecialchars( $source ) . "\n</textarea>"; 00578 $this->addHTML( $text ); 00579 } 00580 00581 $this->returnToMain( false ); 00582 } 00583 00584 function fatalError( $message ) 00585 { 00586 $this->setPageTitle( wfMsg( "internalerror" ) ); 00587 $this->setRobotpolicy( "noindex,nofollow" ); 00588 $this->setArticleRelated( false ); 00589 $this->enableClientCache( false ); 00590 00591 $this->mBodytext = $message; 00592 $this->output(); 00593 wfAbruptExit(); 00594 } 00595 00596 function unexpectedValueError( $name, $val ) 00597 { 00598 $this->fatalError( wfMsg( "unexpected", $name, $val ) ); 00599 } 00600 00601 function fileCopyError( $old, $new ) 00602 { 00603 $this->fatalError( wfMsg( "filecopyerror", $old, $new ) ); 00604 } 00605 00606 function fileRenameError( $old, $new ) 00607 { 00608 $this->fatalError( wfMsg( "filerenameerror", $old, $new ) ); 00609 } 00610 00611 function fileDeleteError( $name ) 00612 { 00613 $this->fatalError( wfMsg( "filedeleteerror", $name ) ); 00614 } 00615 00616 function fileNotFoundError( $name ) 00617 { 00618 $this->fatalError( wfMsg( "filenotfound", $name ) ); 00619 } 00620 00621 // return from error messages or notes 00622 // auto: automatically redirect the user after 10 seconds 00623 // returnto: page title to return to. Default is Main Page. 00624 function returnToMain( $auto = true, $returnto = NULL ) 00625 { 00626 global $wgUser, $wgOut, $wgRequest; 00627 00628 if ( $returnto == NULL ) { 00629 $returnto = $wgRequest->getText( 'returnto' ); 00630 } 00631 00632 $sk = $wgUser->getSkin(); 00633 if ( "" == $returnto ) { 00634 $returnto = wfMsg( "mainpage" ); 00635 } 00636 $link = $sk->makeKnownLink( $returnto, "" ); 00637 00638 $r = wfMsg( "returnto", $link ); 00639 if ( $auto ) { 00640 $titleObj = Title::newFromText( $returnto ); 00641 $wgOut->addMeta( "http:Refresh", "10;url=" . $titleObj->escapeFullURL() ); 00642 } 00643 $wgOut->addHTML( "\n<p>$r</p>\n" ); 00644 } 00645 00646 # This function takes the existing and broken links for the page 00647 # and uses the first 10 of them for META keywords 00648 function addMetaTags () 00649 { 00650 global $wgLinkCache , $wgOut ; 00651 $good = array_keys ( $wgLinkCache->mGoodLinks ) ; 00652 $bad = array_keys ( $wgLinkCache->mBadLinks ) ; 00653 $a = array_merge ( $good , $bad ) ; 00654 $a = array_slice ( $a , 0 , 10 ) ; # 10 keywords max 00655 $a = implode ( "," , $a ) ; 00656 $strip = array( 00657 "/<.*?>/" => '', 00658 "/[_]/" => ' ' 00659 ); 00660 $a = htmlspecialchars(preg_replace(array_keys($strip), array_values($strip),$a )); 00661 00662 $wgOut->addMeta ( "KEYWORDS" , $a ) ; 00663 } 00664 00665 /* private */ function headElement() 00666 { 00667 global $wgDocType, $wgDTD, $wgLanguageCode, $wgOutputEncoding, $wgMimeType; 00668 global $wgUser, $wgLang, $wgRequest; 00669 00670 $xml = ($wgMimeType == 'text/xml'); 00671 if( $xml ) { 00672 $ret = "<" . "?xml version=\"1.0\" encoding=\"$wgOutputEncoding\" ?" . ">\n"; 00673 } else { 00674 $ret = ""; 00675 } 00676 00677 $ret .= "<!DOCTYPE html PUBLIC \"$wgDocType\"\n \"$wgDTD\">\n"; 00678 00679 if ( "" == $this->mHTMLtitle ) { 00680 $this->mHTMLtitle = wfMsg( "pagetitle", $this->mPagetitle ); 00681 } 00682 if( $xml ) { 00683 $xmlbits = "xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\""; 00684 } else { 00685 $xmlbits = ""; 00686 } 00687 $rtl = $wgLang->isRTL() ? " dir='RTL'" : ""; 00688 $ret .= "<html $xmlbits lang=\"$wgLanguageCode\" $rtl>\n"; 00689 $ret .= "<head>\n<title>" . htmlspecialchars( $this->mHTMLtitle ) . "</title>\n"; 00690 array_push( $this->mMetatags, array( "http:Content-type", "$wgMimeType; charset={$wgOutputEncoding}" ) ); 00691 00692 $ret .= $this->getHeadLinks(); 00693 global $wgStylePath; 00694 if( $this->isPrintable() ) { 00695 $media = ""; 00696 } else { 00697 $media = "media='print'"; 00698 } 00699 $printsheet = htmlspecialchars( "$wgStylePath/wikiprintable.css" ); 00700 $ret .= "<link rel='stylesheet' type='text/css' $media href='$printsheet' />\n"; 00701 00702 $sk = $wgUser->getSkin(); 00703 $ret .= $sk->getHeadScripts(); 00704 $ret .= $this->mScripts; 00705 $ret .= $sk->getUserStyles(); 00706 00707 $ret .= "</head>\n"; 00708 return $ret; 00709 } 00710 00711 function getHeadLinks() { 00712 global $wgRequest, $wgStylePath; 00713 $ret = ""; 00714 foreach ( $this->mMetatags as $tag ) { 00715 if ( 0 == strcasecmp( "http:", substr( $tag[0], 0, 5 ) ) ) { 00716 $a = "http-equiv"; 00717 $tag[0] = substr( $tag[0], 5 ); 00718 } else { 00719 $a = "name"; 00720 } 00721 $ret .= "<meta $a=\"{$tag[0]}\" content=\"{$tag[1]}\" />\n"; 00722 } 00723 $p = $this->mRobotpolicy; 00724 if ( "" == $p ) { $p = "index,follow"; } 00725 $ret .= "<meta name=\"robots\" content=\"$p\" />\n"; 00726 00727 if ( count( $this->mKeywords ) > 0 ) { 00728 $strip = array( 00729 "/<.*?>/" => '', 00730 "/[_]/" => ' ' 00731 ); 00732 $ret .= "<meta name=\"keywords\" content=\"" . 00733 htmlspecialchars(preg_replace(array_keys($strip), array_values($strip),implode( ",", $this->mKeywords ))) . "\" />\n"; 00734 } 00735 foreach ( $this->mLinktags as $tag ) { 00736 $ret .= "<link"; 00737 foreach( $tag as $attr => $val ) { 00738 $ret .= " $attr=\"" . htmlspecialchars( $val ) . "\""; 00739 } 00740 $ret .= " />\n"; 00741 } 00742 if( $this->isSyndicated() ) { 00743 # FIXME: centralize the mime-type and name information in Feed.php 00744 $link = $wgRequest->escapeAppendQuery( "feed=rss" ); 00745 $ret .= "<link rel='alternate' type='application/rss+xml' title='RSS 2.0' href='$link' />\n"; 00746 $link = $wgRequest->escapeAppendQuery( "feed=atom" ); 00747 $ret .= "<link rel='alternate' type='application/rss+atom' title='Atom 0.3' href='$link' />\n"; 00748 } 00749 # FIXME: get these working 00750 # $fix = htmlspecialchars( $wgStylePath . "/ie-png-fix.js" ); 00751 # $ret .= "<!--[if gte IE 5.5000]><script type='text/javascript' src='$fix'></script><![endif]-->"; 00752 return $ret; 00753 } 00754 } 00755 ?>

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