X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2FOutputPage.php;h=92b416e3fe2761f468f189c39383aa887c32ff39;hb=f3c64eca2f28d0d3df9bedbadadac41a29304a2a;hp=bb12b4c8ce908dd627a23a4c3d6a4a6575d97a8b;hpb=cd0a89520dec7b2c5de5ff5a519e083bd546a798;p=lhc%2Fweb%2Fwiklou.git
diff --git a/includes/OutputPage.php b/includes/OutputPage.php
index bb12b4c8ce..f9859e6f9e 100644
--- a/includes/OutputPage.php
+++ b/includes/OutputPage.php
@@ -1,409 +1,454 @@
-
-# See design.doc
-
-function linkToMathImage ( $tex, $outputhash )
-{
- global $wgMathPath;
- return "";
-}
-
-function renderMath( $tex )
-{
- global $wgUser, $wgMathDirectory, $wgTmpDirectory, $wgInputEncoding;
- $mf = wfMsg( "math_failure" );
- $munk = wfMsg( "math_unknown_error" );
-
- $fname = "renderMath";
-
- $math = $wgUser->getOption("math");
- if ($math == 3)
- return ('$ '.wfEscapeHTML($tex).' $');
-
- $md5 = md5($tex);
- $md5_sql = mysql_escape_string(pack("H32", $md5));
- if ($math == 0)
- $sql = "SELECT math_outputhash FROM math WHERE math_inputhash = '".$md5_sql."'";
- else
- $sql = "SELECT math_outputhash,math_html_conservativeness,math_html FROM math WHERE math_inputhash = '".$md5_sql."'";
-
- $res = wfQuery( $sql, $fname );
- if ( wfNumRows( $res ) == 0 )
- {
- $cmd = "./math/texvc ".escapeshellarg($wgTmpDirectory)." ".
- escapeshellarg($wgMathDirectory)." ".escapeshellarg($tex)." ".escapeshellarg($wgInputEncoding);
- $contents = `$cmd`;
-
- if (strlen($contents) == 0)
- return "".$mf." (".$munk."): ".wfEscapeHTML($tex)."";
- $retval = substr ($contents, 0, 1);
- if (($retval == "C") || ($retval == "M") || ($retval == "L")) {
- if ($retval == "C")
- $conservativeness = 2;
- else if ($retval == "M")
- $conservativeness = 1;
- else
- $conservativeness = 0;
- $outdata = substr ($contents, 33);
-
- $i = strpos($outdata, "\000");
-
- $outhtml = substr($outdata, 0, $i);
- $mathml = substr($outdata, $i+1);
-
- $sql_html = "'".mysql_escape_string($outhtml)."'";
- $sql_mathml = "'".mysql_escape_string($mathml)."'";
- } else if (($retval == "c") || ($retval == "m") || ($retval == "l")) {
- $outhtml = substr ($contents, 33);
- if ($retval == "c")
- $conservativeness = 2;
- else if ($retval == "m")
- $conservativeness = 1;
- else
- $conservativeness = 0;
- $sql_html = "'".mysql_escape_string($outhtml)."'";
- $mathml = '';
- $sql_mathml = 'NULL';
- } else if ($retval == "X") {
- $outhtml = '';
- $mathml = substr ($contents, 33);
- $sql_html = 'NULL';
- $sql_mathml = "'".mysql_escape_string($mathml)."'";
- $conservativeness = 0;
- } else if ($retval == "+") {
- $outhtml = '';
- $mathml = '';
- $sql_html = 'NULL';
- $sql_mathml = 'NULL';
- $conservativeness = 0;
- } else {
- if ($retval == "E")
- $errmsg = wfMsg( "math_lexing_error" );
- else if ($retval == "S")
- $errmsg = wfMsg( "math_syntax_error" );
- else if ($retval == "F")
- $errmsg = wfMsg( "math_unknown_function" );
- else
- $errmsg = $munk;
- return "
".$mf." (".$errmsg.substr($contents, 1)."): ".wfEscapeHTML($tex)."
";
- }
+".$mf." (".$munk."): ".wfEscapeHTML($tex)."";
+/**
+ * This is not a valid entry point, perform no further processing unless MEDIAWIKI is defined
+ */
+if( defined( 'MEDIAWIKI' ) ) {
- $outmd5_sql = mysql_escape_string(pack("H32", $outmd5));
+# See design.doc
- $sql = "REPLACE INTO math VALUES ('".$md5_sql."', '".$outmd5_sql."', ".$conservativeness.", ".$sql_html.", ".$sql_mathml.")";
-
- $res = wfQuery( $sql, $fname );
- # we don't really care if it fails
-
- if (($math == 0) || ($rpage->math_html == '') || (($math == 1) && ($conservativeness != 2)) || (($math == 4) && ($conservativeness == 0)))
- return linkToMathImage($tex, $outmd5);
- else
- return $outhtml;
- } else {
- $rpage = wfFetchObject ( $res );
- $outputhash = unpack( "H32md5", $rpage->math_outputhash . " " );
- $outputhash = $outputhash ['md5'];
-
- if (($math == 0) || ($rpage->math_html == '') || (($math == 1) && ($rpage->math_html_conservativeness != 2)) || (($math == 4) && ($rpage->math_html_conservativeness == 0)))
- return linkToMathImage ( $tex, $outputhash );
- else
- return $rpage->math_html;
- }
-}
+if($wgUseTeX) require_once( 'Math.php' );
+/**
+ * @todo document
+ * @package MediaWiki
+ */
class OutputPage {
var $mHeaders, $mCookies, $mMetatags, $mKeywords;
var $mLinktags, $mPagetitle, $mBodytext, $mDebugtext;
var $mHTMLtitle, $mRobotpolicy, $mIsarticle, $mPrintable;
- var $mSubtitle, $mRedirect, $mAutonumber, $mHeadtext;
- var $mLastModified;
-
- var $mDTopen, $mLastSection; # Used for processing DL, PRE
- var $mLanguageLinks, $mSupressQuickbar;
-
- function OutputPage()
- {
+ var $mSubtitle, $mRedirect;
+ var $mLastModified, $mCategoryLinks;
+ var $mScripts, $mLinkColours;
+
+ var $mSuppressQuickbar;
+ var $mOnloadHandler;
+ var $mDoNothing;
+ var $mContainsOldMagic, $mContainsNewMagic;
+ var $mIsArticleRelated;
+ var $mParserOptions;
+ var $mShowFeedLinks = false;
+ var $mEnableClientCache = true;
+
+ /**
+ * Constructor
+ * Initialise private variables
+ */
+ function OutputPage() {
$this->mHeaders = $this->mCookies = $this->mMetatags =
$this->mKeywords = $this->mLinktags = array();
$this->mHTMLtitle = $this->mPagetitle = $this->mBodytext =
- $this->mLastSection = $this->mRedirect = $this->mLastModified =
- $this->mSubtitle = $this->mDebugtext = $this->mRobotpolicy = "";
- $this->mIsarticle = $this->mPrintable = true;
- $this->mSupressQuickbar = $this->mDTopen = $this->mPrintable = false;
+ $this->mRedirect = $this->mLastModified =
+ $this->mSubtitle = $this->mDebugtext = $this->mRobotpolicy =
+ $this->mOnloadHandler = '';
+ $this->mIsArticleRelated = $this->mIsarticle = $this->mPrintable = true;
+ $this->mSuppressQuickbar = $this->mPrintable = false;
$this->mLanguageLinks = array();
- $this->mAutonumber = 0;
+ $this->mCategoryLinks = array() ;
+ $this->mDoNothing = false;
+ $this->mContainsOldMagic = $this->mContainsNewMagic = 0;
+ $this->mParserOptions = ParserOptions::newFromUser( $temp = NULL );
+ $this->mSquidMaxage = 0;
+ $this->mScripts = '';
}
- function addHeader( $name, $val ) { array_push( $this->mHeaders, "$name: $val" ) ; }
+ function addHeader( $name, $val ) { array_push( $this->mHeaders, $name.': '.$val ) ; }
function addCookie( $name, $val ) { array_push( $this->mCookies, array( $name, $val ) ); }
- function redirect( $url ) { $this->mRedirect = $url; }
+ function redirect( $url, $responsecode = '302' ) { $this->mRedirect = $url; $this->mRedirectCode = $responsecode; }
# To add an http-equiv meta tag, precede the name with "http:"
function addMeta( $name, $val ) { array_push( $this->mMetatags, array( $name, $val ) ); }
function addKeyword( $text ) { array_push( $this->mKeywords, $text ); }
- function addLink( $rel, $rev, $target ) { array_push( $this->mLinktags, array( $rel, $rev, $target ) ); }
+ function addScript( $script ) { $this->mScripts .= $script; }
+ function getScript() { return $this->mScripts; }
+
+ function addLink( $linkarr ) {
+ # $linkarr should be an associative array of attributes. We'll escape on output.
+ array_push( $this->mLinktags, $linkarr );
+ }
- function checkLastModified ( $timestamp )
- {
+ function addMetadataLink( $linkarr ) {
+ # note: buggy CC software only reads first "meta" link
+ static $haveMeta = false;
+ $linkarr['rel'] = ($haveMeta) ? 'alternate meta' : 'meta';
+ $this->addLink( $linkarr );
+ $haveMeta = true;
+ }
+
+ /**
+ * checkLastModified tells the client to use the client-cached page if
+ * possible. If sucessful, the OutputPage is disabled so that
+ * any future call to OutputPage->output() have no effect. The method
+ * returns true iff cache-ok headers was sent.
+ */
+ function checkLastModified ( $timestamp ) {
global $wgLang, $wgCachePages, $wgUser;
- if( !$wgCachePages ) return;
+ $timestamp=wfTimestamp(TS_MW,$timestamp);
+ if( !$wgCachePages ) {
+ wfDebug( "CACHE DISABLED\n", false );
+ return;
+ }
if( preg_match( '/MSIE ([1-4]|5\.0)/', $_SERVER["HTTP_USER_AGENT"] ) ) {
# IE 5.0 has probs with our caching
- #wfDebug( "-- bad client, not caching\n", false );
+ wfDebug( "-- bad client, not caching\n", false );
return;
}
- if( $wgUser->getOption( "nocache" ) ) return;
-
- if( $_SERVER["HTTP_IF_MODIFIED_SINCE"] != "" ) {
- $ismodsince = wfUnix2Timestamp( strtotime( $_SERVER["HTTP_IF_MODIFIED_SINCE"] ) );
- #wfDebug( "-- client send If-Modified-Since: " . $_SERVER["HTTP_IF_MODIFIED_SINCE"] . "\n", false );
- $lastmod = gmdate( "D, j M Y H:i:s", wfTimestamp2Unix(
- max( $timestamp, $wgUser->mTouched ) ) ) . " GMT";
- #wfDebug( "-- we might send Last-Modified : $lastmod\n", false );
-
+ if( $wgUser->getOption( 'nocache' ) ) {
+ wfDebug( "USER DISABLED CACHE\n", false );
+ return;
+ }
+
+ $lastmod = gmdate( 'D, j M Y H:i:s', wfTimestamp(TS_UNIX, max( $timestamp, $wgUser->mTouched ) ) ) . ' GMT';
+
+ if( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
+ # IE sends sizes after the date like this:
+ # Wed, 20 Aug 2003 06:51:19 GMT; length=5202
+ # this breaks strtotime().
+ $modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
+ $ismodsince = wfTimestamp( TS_MW, strtotime( $modsince ) );
+ wfDebug( "-- client send If-Modified-Since: " . $modsince . "\n", false );
+ wfDebug( "-- we might send Last-Modified : $lastmod\n", false );
if( ($ismodsince >= $timestamp ) and $wgUser->validateCache( $ismodsince ) ) {
# Make sure you're in a place you can leave when you call us!
header( "HTTP/1.0 304 Not Modified" );
- header( "Expires: Mon, 15 Jan 2001 00:00:00 GMT" ); # Cachers always validate the page!
- header( "Cache-Control: private, must-revalidate, max-age=0" );
- header( "Last-Modified: {$lastmod}" );
- #wfDebug( "CACHED client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false );
- exit;
+ $this->mLastModified = $lastmod;
+ $this->sendCacheControl();
+ wfDebug( "CACHED client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false );
+ $this->disable();
+ return true;
} else {
- #wfDebug( "READY client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false );
+ wfDebug( "READY client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false );
$this->mLastModified = $lastmod;
}
+ } else {
+ wfDebug( "We're confused.\n", false );
+ $this->mLastModified = $lastmod;
+ }
+ }
+
+ function getPageTitleActionText () {
+ global $action;
+ switch($action) {
+ case 'edit':
+ return wfMsg('edit');
+ case 'history':
+ return wfMsg('history_short');
+ case 'protect':
+ return wfMsg('protect');
+ case 'unprotect':
+ return wfMsg('unprotect');
+ case 'delete':
+ return wfMsg('delete');
+ case 'watch':
+ return wfMsg('watch');
+ case 'unwatch':
+ return wfMsg('unwatch');
+ case 'submit':
+ return wfMsg('preview');
+ case 'info':
+ return wfMsg('info_short');
+ default:
+ return '';
}
}
function setRobotpolicy( $str ) { $this->mRobotpolicy = $str; }
- function setHTMLtitle( $name ) { $this->mHTMLtitle = $name; }
- function setPageTitle( $name ) { $this->mPagetitle = $name; }
+ function setHTMLTitle( $name ) {$this->mHTMLtitle = $name; }
+ function setPageTitle( $name ) {
+ global $action, $wgContLang;
+ $name = $wgContLang->convert($name, true);
+ $this->mPagetitle = $name;
+ if(!empty($action)) {
+ $taction = $this->getPageTitleActionText();
+ if( !empty( $taction ) ) {
+ $name .= ' - '.$taction;
+ }
+ }
+ $this->setHTMLTitle( $name . ' - ' . wfMsg( 'wikititlesuffix' ) );
+ }
+ function getHTMLTitle() { return $this->mHTMLtitle; }
function getPageTitle() { return $this->mPagetitle; }
function setSubtitle( $str ) { $this->mSubtitle = $str; }
function getSubtitle() { return $this->mSubtitle; }
- function setArticleFlag( $v ) { $this->mIsarticle = $v; }
function isArticle() { return $this->mIsarticle; }
function setPrintable() { $this->mPrintable = true; }
function isPrintable() { return $this->mPrintable; }
+ function setSyndicated( $show = true ) { $this->mShowFeedLinks = $show; }
+ function isSyndicated() { return $this->mShowFeedLinks; }
+ function setOnloadHandler( $js ) { $this->mOnloadHandler = $js; }
+ function getOnloadHandler() { return $this->mOnloadHandler; }
+ function disable() { $this->mDoNothing = true; }
- function getLanguageLinks() {
- global $wgUseNewInterlanguage, $wgTitle, $wgLanguageCode;
- global $wgDBconnection, $wgDBname, $wgDBintlname;
-
- if ( ! $wgUseNewInterlanguage )
- return $this->mLanguageLinks;
-
- mysql_select_db( $wgDBintlname, $wgDBconnection ) or die(
- htmlspecialchars(mysql_error()) );
+ function setArticleRelated( $v ) {
+ $this->mIsArticleRelated = $v;
+ if ( !$v ) {
+ $this->mIsarticle = false;
+ }
+ }
+ function setArticleFlag( $v ) {
+ $this->mIsarticle = $v;
+ if ( $v ) {
+ $this->mIsArticleRelated = $v;
+ }
+ }
- $list = array();
- $sql = "SELECT * FROM ilinks WHERE lang_from=\"" .
- "{$wgLanguageCode}\" AND title_from=\"" . $wgTitle->getDBkey() . "\"";
- $res = mysql_query( $sql, $wgDBconnection );
+ function isArticleRelated() { return $this->mIsArticleRelated; }
- while ( $q = mysql_fetch_object ( $res ) ) {
- $list[] = $q->lang_to . ":" . $q->title_to;
- }
- mysql_free_result( $res );
- mysql_select_db( $wgDBname, $wgDBconnection ) or die(
- htmlspecialchars(mysql_error()) );
+ function getLanguageLinks() { return $this->mLanguageLinks; }
+ function addLanguageLinks($newLinkArray) {
+ $this->mLanguageLinks += $newLinkArray;
+ }
+ function setLanguageLinks($newLinkArray) {
+ $this->mLanguageLinks = $newLinkArray;
+ }
- return $list;
+ function getCategoryLinks() {
+ return $this->mCategoryLinks;
+ }
+ function addCategoryLinks($newLinkArray) {
+ $this->mCategoryLinks += $newLinkArray;
+ }
+ function setCategoryLinks($newLinkArray) {
+ $this->mCategoryLinks += $newLinkArray;
}
- function supressQuickbar() { $this->mSupressQuickbar = true; }
- function isQuickbarSupressed() { return $this->mSupressQuickbar; }
+ function suppressQuickbar() { $this->mSuppressQuickbar = true; }
+ function isQuickbarSuppressed() { return $this->mSuppressQuickbar; }
function addHTML( $text ) { $this->mBodytext .= $text; }
- function addHeadtext( $text ) { $this->mHeadtext .= $text; }
+ function clearHTML() { $this->mBodytext = ''; }
function debug( $text ) { $this->mDebugtext .= $text; }
- # First pass--just handle sections, pass the rest off
- # to doWikiPass2() which does all the real work.
- #
-
- function addWikiText( $text, $linestart = true )
- {
- global $wgUseTeX;
- wfProfileIn( "OutputPage::addWikiText" );
- $unique = "3iyZiyA7iMwg5rhxP0Dcc9oTnj8qD1jm1Sfv4";
- $unique2 = "4LIQ9nXtiYFPCSfitVwDw7EYwQlL4GeeQ7qSO";
- $unique3 = "fPaA8gDfdLBqzj68Yjg9Hil3qEF8JGO0uszIp";
- $nwlist = array();
- $nwsecs = 0;
- $mathlist = array();
- $mathsecs = 0;
- $prelist = array ();
- $presecs = 0;
- $stripped = "";
- $stripped2 = "";
- $stripped3 = "";
-
- while ( "" != $text ) {
- $p = preg_split( "/<\\s*nowiki\\s*>/i", $text, 2 );
- $stripped .= $p[0];
- if ( ( count( $p ) < 2 ) || ( "" == $p[1] ) ) { $text = ""; }
- else {
- $q = preg_split( "/<\\/\\s*nowiki\\s*>/i", $p[1], 2 );
- ++$nwsecs;
- $nwlist[$nwsecs] = wfEscapeHTMLTagsOnly($q[0]);
- $stripped .= $unique;
- $text = $q[1];
- }
- }
+ function setParserOptions( $options ) {
+ return wfSetVar( $this->mParserOptions, $options );
+ }
- if( $wgUseTeX ) {
- while ( "" != $stripped ) {
- $p = preg_split( "/<\\s*math\\s*>/i", $stripped, 2 );
- $stripped2 .= $p[0];
- if ( ( count( $p ) < 2 ) || ( "" == $p[1] ) ) { $stripped = ""; }
- else {
- $q = preg_split( "/<\\/\\s*math\\s*>/i", $p[1], 2 );
- ++$mathsecs;
- $mathlist[$mathsecs] = renderMath($q[0]);
- $stripped2 .= $unique2;
- $stripped = $q[1];
- }
- }
- } else {
- $stripped2 = $stripped;
- }
+ /**
+ * Convert wikitext to HTML and add it to the buffer
+ */
+ function addWikiText( $text, $linestart = true ) {
+ global $wgParser, $wgTitle, $wgUseTidy;
- while ( "" != $stripped2 ) {
- $p = preg_split( "/<\\s*pre\\s*>/i", $stripped2, 2 );
- $stripped3 .= $p[0];
- if ( ( count( $p ) < 2 ) || ( "" == $p[1] ) ) { $stripped2 = ""; }
- else {
- $q = preg_split( "/<\\/\\s*pre\\s*>/i", $p[1], 2 );
- ++$presecs;
- $prelist[$presecs] = "". wfEscapeHTMLTagsOnly($q[0]). "
";
- $stripped3 .= $unique3;
- $stripped2 = $q[1];
- }
- }
+ $parserOutput = $wgParser->parse( $text, $wgTitle, $this->mParserOptions, $linestart );
+ $this->mLanguageLinks += $parserOutput->getLanguageLinks();
+ $this->mCategoryLinks += $parserOutput->getCategoryLinks();
+ $this->addHTML( $parserOutput->getText() );
+ }
- $text = $this->doWikiPass2( $stripped3, $linestart );
+ /**
+ * Add wikitext to the buffer, assuming that this is the primary text for a page view
+ * Saves the text into the parser cache if possible
+ */
+ function addPrimaryWikiText( $text, $cacheArticle ) {
+ global $wgParser, $wgParserCache, $wgUser, $wgTitle, $wgUseTidy;
- for ( $i = 1; $i <= $presecs; ++$i ) {
- $text = preg_replace( "/{$unique3}/", str_replace( '$', '\$', $prelist[$i] ), $text, 1 );
- }
+ $parserOutput = $wgParser->parse( $text, $wgTitle, $this->mParserOptions, true );
- for ( $i = 1; $i <= $mathsecs; ++$i ) {
- $text = preg_replace( "/{$unique2}/", str_replace( '$', '\$', $mathlist[$i] ), $text, 1 );
+ $text = $parserOutput->getText();
+
+ if ( $cacheArticle ) {
+ $wgParserCache->save( $parserOutput, $cacheArticle, $wgUser );
}
- for ( $i = 1; $i <= $nwsecs; ++$i ) {
- $text = preg_replace( "/{$unique}/", str_replace( '$', '\$', $nwlist[$i] ), $text, 1 );
- }
+ $this->mLanguageLinks += $parserOutput->getLanguageLinks();
+ $this->mCategoryLinks += $parserOutput->getCategoryLinks();
$this->addHTML( $text );
- wfProfileOut();
+ }
+
+ /**
+ * Add the output of a QuickTemplate to the output buffer
+ * @param QuickTemplate $template
+ */
+ function addTemplate( &$template ) {
+ ob_start();
+ $template->execute();
+ $this->addHtml( ob_get_contents() );
+ ob_end_clean();
+ }
+
+ /**
+ * @param $article
+ * @param $user
+ */
+ function tryParserCache( $article, $user ) {
+ global $wgParserCache;
+ $parserOutput = $wgParserCache->get( $article, $user );
+ if ( $parserOutput !== false ) {
+ $this->mLanguageLinks += $parserOutput->getLanguageLinks();
+ $this->mCategoryLinks += $parserOutput->getCategoryLinks();
+ $this->addHTML( $parserOutput->getText() );
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Set the maximum cache time on the Squid in seconds
+ * @param $maxage
+ */
+ function setSquidMaxage( $maxage ) {
+ $this->mSquidMaxage = $maxage;
+ }
+
+ /**
+ * Use enableClientCache(false) to force it to send nocache headers
+ * @param $state
+ */
+ function enableClientCache( $state ) {
+ return wfSetVar( $this->mEnableClientCache, $state );
}
function sendCacheControl() {
- if( $this->mLastModified != "" ) {
- header( "Cache-Control: private, must-revalidate, max-age=0" );
- header( "Last-modified: {$this->mLastModified}" );
+ global $wgUseSquid, $wgUseESI;
+ # FIXME: This header may cause trouble with some versions of Internet Explorer
+ header( 'Vary: Accept-Encoding, Cookie' );
+ if( $this->mEnableClientCache ) {
+ if( $wgUseSquid && ! isset( $_COOKIE[ini_get( 'session.name') ] ) &&
+ ! $this->isPrintable() && $this->mSquidMaxage != 0 )
+ {
+ if ( $wgUseESI ) {
+ # We'll purge the proxy cache explicitly, but require end user agents
+ # to revalidate against the proxy on each visit.
+ # Surrogate-Control controls our Squid, Cache-Control downstream caches
+ wfDebug( "** proxy caching with ESI; {$this->mLastModified} **\n", false );
+ # start with a shorter timeout for initial testing
+ # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"');
+ header( 'Surrogate-Control: max-age='.$wgSquidMaxage.'+'.$this->mSquidMaxage.', content="ESI/1.0"');
+ header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' );
+ } else {
+ # We'll purge the proxy cache for anons explicitly, but require end user agents
+ # to revalidate against the proxy on each visit.
+ # IMPORTANT! The Squid needs to replace the Cache-Control header with
+ # Cache-Control: s-maxage=0, must-revalidate, max-age=0
+ wfDebug( "** local proxy caching; {$this->mLastModified} **\n", false );
+ # start with a shorter timeout for initial testing
+ # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
+ header( 'Cache-Control: s-maxage='.$this->mSquidMaxage.', must-revalidate, max-age=0' );
+ }
+ } else {
+ # We do want clients to cache if they can, but they *must* check for updates
+ # on revisiting the page.
+ wfDebug( "** private caching; {$this->mLastModified} **\n", false );
+ header( "Expires: -1" );
+ header( "Cache-Control: private, must-revalidate, max-age=0" );
+ }
+ if($this->mLastModified) header( "Last-modified: {$this->mLastModified}" );
} else {
- header( "Cache-Control: no-cache" ); # Experimental - see below
- header( "Pragma: no-cache" );
- header( "Last-modified: " . gmdate( "D, j M Y H:i:s" ) . " GMT" );
+ wfDebug( "** no caching **\n", false );
+
+ # In general, the absence of a last modified header should be enough to prevent
+ # the client from using its cache. We send a few other things just to make sure.
+ header( 'Expires: -1' );
+ header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
+ header( 'Pragma: no-cache' );
}
- header( "Expires: Mon, 15 Jan 2001 00:00:00 GMT" ); # Cachers always validate the page!
}
-
- # Finally, all the text has been munged and accumulated into
- # the object, let's actually output it:
- #
- function output()
- {
+
+ /**
+ * Finally, all the text has been munged and accumulated into
+ * the object, let's actually output it:
+ */
+ function output() {
global $wgUser, $wgLang, $wgDebugComments, $wgCookieExpiration;
- global $wgInputEncoding, $wgOutputEncoding, $wgLanguageCode;
- wfProfileIn( "OutputPage::output" );
+ global $wgInputEncoding, $wgOutputEncoding, $wgContLanguageCode;
+ global $wgDebugRedirects, $wgMimeType, $wgProfiler;
+
+ if( $this->mDoNothing ){
+ return;
+ }
+ $fname = 'OutputPage::output';
+ wfProfileIn( $fname );
$sk = $wgUser->getSkin();
- wfProfileIn( "OutputPage::output-headers" );
- $this->sendCacheControl();
+ if ( '' != $this->mRedirect ) {
+ if( substr( $this->mRedirect, 0, 4 ) != 'http' ) {
+ # Standards require redirect URLs to be absolute
+ global $wgServer;
+ $this->mRedirect = $wgServer . $this->mRedirect;
+ }
+ if( $this->mRedirectCode == '301') {
+ if( !$wgDebugRedirects ) {
+ header("HTTP/1.1 {$this->mRedirectCode} Moved Permanently");
+ }
+ $this->mLastModified = gmdate( 'D, j M Y H:i:s' ) . ' GMT';
+ }
- header( "Content-type: text/html; charset={$wgOutputEncoding}" );
- header( "Content-language: {$wgLanguageCode}" );
-
- if ( "" != $this->mRedirect ) {
- header( "Location: {$this->mRedirect}" );
- wfProfileOut();
+ $this->sendCacheControl();
+
+ if( $wgDebugRedirects ) {
+ $url = htmlspecialchars( $this->mRedirect );
+ print "\n\nRedirect\n\n\n";
+ print "Location: $url
\n";
+ print "\n\n";
+ } else {
+ header( 'Location: '.$this->mRedirect );
+ }
+ if ( isset( $wgProfiler ) ) { wfDebug( $wgProfiler->getOutput() ); }
return;
}
+
+ # Buffer output; final headers may depend on later processing
+ ob_start();
+
+ $this->transformBuffer();
+
+ # Disable temporary placeholders, so that the skin produces HTML
+ $sk->postParseLinkColour( false );
+
+ header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" );
+ header( 'Content-language: '.$wgContLanguageCode );
+
$exp = time() + $wgCookieExpiration;
foreach( $this->mCookies as $name => $val ) {
- setcookie( $name, $val, $exp, "/" );
+ setcookie( $name, $val, $exp, '/' );
}
- wfProfileOut();
-
- wfProfileIn( "OutputPage::output-middle" );
- $sk->initPage();
- $this->out( $this->headElement() );
- $this->out( "\ngetBodyOptions();
- foreach ( $ops as $name => $val ) {
- $this->out( " $name='$val'" );
- }
- $this->out( ">\n" );
- if ( $wgDebugComments ) {
- $this->out( "\n" );
- }
- $this->out( $sk->beforeContent() );
- wfProfileOut();
+ wfProfileIn( 'Output-skin' );
+ $sk->outputPage( $this );
+ wfProfileOut( 'Output-skin' );
- wfProfileIn( "OutputPage::output-bodytext" );
- $this->out( $this->mBodytext );
- wfProfileOut();
- wfProfileIn( "OutputPage::output-after" );
- $this->out( $sk->afterContent() );
- wfProfileOut();
-
- wfProfileOut(); # A hack - we can't report after here
- $this->out( $this->reportTime() );
-
- $this->out( "\n