Index: trunk/phase3/includes/SpecialVersion.php |
— | — | @@ -44,6 +44,208 @@ |
45 | 45 | /** |
46 | 46 | * @static |
47 | 47 | */ |
| 48 | +<?php |
| 49 | +/** |
| 50 | + * Copyright (C) 2004 Gabriel Wicke <wicke@wikidev.net> |
| 51 | + * http://wikidev.net/ |
| 52 | + * Based on PageHistory and SpecialExport |
| 53 | + * |
| 54 | + * License: GPL (http://www.gnu.org/copyleft/gpl.html) |
| 55 | + * |
| 56 | + * @author Gabriel Wicke <wicke@wikidev.net> |
| 57 | + * @package MediaWiki |
| 58 | + */ |
| 59 | + |
| 60 | +/** */ |
| 61 | +require_once( 'Revision.php' ); |
| 62 | + |
| 63 | +/** |
| 64 | + * @todo document |
| 65 | + * @package MediaWiki |
| 66 | + */ |
| 67 | +class RawPage { |
| 68 | + var $mArticle, $mTitle, $mRequest; |
| 69 | + var $mOldId, $mGen, $mCharset; |
| 70 | + var $mSmaxage, $mMaxage; |
| 71 | + var $mContentType, $mExpandTemplates; |
| 72 | + |
| 73 | + function RawPage( &$article, $request = false ) { |
| 74 | + global $wgRequest, $wgInputEncoding, $wgSquidMaxage, $wgJsMimeType; |
| 75 | + |
| 76 | + $allowedCTypes = array('text/x-wiki', $wgJsMimeType, 'text/css', 'application/x-zope-edit'); |
| 77 | + $this->mArticle =& $article; |
| 78 | + $this->mTitle =& $article->mTitle; |
| 79 | + |
| 80 | + if ( $request === false ) { |
| 81 | + $this->mRequest =& $wgRequest; |
| 82 | + } else { |
| 83 | + $this->mRequest = $request; |
| 84 | + } |
| 85 | + |
| 86 | + $ctype = $this->mRequest->getVal( 'ctype' ); |
| 87 | + $smaxage = $this->mRequest->getIntOrNull( 'smaxage', $wgSquidMaxage ); |
| 88 | + $maxage = $this->mRequest->getInt( 'maxage', $wgSquidMaxage ); |
| 89 | + $this->mExpandTemplates = $this->mRequest->getVal( 'templates' ) === 'expand'; |
| 90 | + |
| 91 | + $oldid = $this->mRequest->getInt( 'oldid' ); |
| 92 | + switch ( $wgRequest->getText( 'direction' ) ) { |
| 93 | + case 'next': |
| 94 | + # output next revision, or nothing if there isn't one |
| 95 | + if ( $oldid ) { |
| 96 | + $oldid = $this->mTitle->getNextRevisionId( $oldid ); |
| 97 | + } |
| 98 | + $oldid = $oldid ? $oldid : -1; |
| 99 | + break; |
| 100 | + case 'prev': |
| 101 | + # output previous revision, or nothing if there isn't one |
| 102 | + if ( ! $oldid ) { |
| 103 | + # get the current revision so we can get the penultimate one |
| 104 | + $this->mArticle->getTouched(); |
| 105 | + $oldid = $this->mArticle->mLatest; |
| 106 | + } |
| 107 | + $prev = $this->mTitle->getPreviousRevisionId( $oldid ); |
| 108 | + $oldid = $prev ? $prev : -1 ; |
| 109 | + break; |
| 110 | + case 'cur': |
| 111 | + $oldid = 0; |
| 112 | + break; |
| 113 | + } |
| 114 | + $this->mOldId = $oldid; |
| 115 | + |
| 116 | + # special case for 'generated' raw things: user css/js |
| 117 | + $gen = $this->mRequest->getVal( 'gen' ); |
| 118 | + |
| 119 | + if($gen == 'css') { |
| 120 | + $this->mGen = $gen; |
| 121 | + if( is_null( $smaxage ) ) $smaxage = $wgSquidMaxage; |
| 122 | + if($ctype == '') $ctype = 'text/css'; |
| 123 | + } elseif ($gen == 'js') { |
| 124 | + $this->mGen = $gen; |
| 125 | + if( is_null( $smaxage ) ) $smaxage = $wgSquidMaxage; |
| 126 | + if($ctype == '') $ctype = $wgJsMimeType; |
| 127 | + } else { |
| 128 | + $this->mGen = false; |
| 129 | + } |
| 130 | + $this->mCharset = $wgInputEncoding; |
| 131 | + $this->mSmaxage = intval( $smaxage ); |
| 132 | + $this->mMaxage = $maxage; |
| 133 | + if ( $ctype == '' or ! in_array( $ctype, $allowedCTypes ) ) { |
| 134 | + $this->mContentType = 'text/x-wiki'; |
| 135 | + } else { |
| 136 | + $this->mContentType = $ctype; |
| 137 | + } |
| 138 | + } |
| 139 | + |
| 140 | + function view() { |
| 141 | + global $wgOut, $wgScript; |
| 142 | + |
| 143 | + if( isset( $_SERVER['SCRIPT_URL'] ) ) { |
| 144 | + # Normally we use PHP_SELF to get the URL to the script |
| 145 | + # as it was called, minus the query string. |
| 146 | + # |
| 147 | + # Some sites use Apache rewrite rules to handle subdomains, |
| 148 | + # and have PHP set up in a weird way that causes PHP_SELF |
| 149 | + # to contain the rewritten URL instead of the one that the |
| 150 | + # outside world sees. |
| 151 | + # |
| 152 | + # If in this mode, use SCRIPT_URL instead, which mod_rewrite |
| 153 | + # provides containing the "before" URL. |
| 154 | + $url = $_SERVER['SCRIPT_URL']; |
| 155 | + } else { |
| 156 | + $url = $_SERVER['PHP_SELF']; |
| 157 | + } |
| 158 | + |
| 159 | + $ua = @$_SERVER['HTTP_USER_AGENT']; |
| 160 | + if( strcmp( $wgScript, $url ) && strpos( $ua, 'MSIE' ) !== false ) { |
| 161 | + # Internet Explorer will ignore the Content-Type header if it |
| 162 | + # thinks it sees a file extension it recognizes. Make sure that |
| 163 | + # all raw requests are done through the script node, which will |
| 164 | + # have eg '.php' and should remain safe. |
| 165 | + # |
| 166 | + # We used to redirect to a canonical-form URL as a general |
| 167 | + # backwards-compatibility / good-citizen nice thing. However |
| 168 | + # a lot of servers are set up in buggy ways, resulting in |
| 169 | + # redirect loops which hang the browser until the CSS load |
| 170 | + # times out. |
| 171 | + # |
| 172 | + # Just return a 403 Forbidden and get it over with. |
| 173 | + wfHttpError( 403, 'Forbidden', |
| 174 | + 'Raw pages must be accessed through the primary script entry point.' ); |
| 175 | + return; |
| 176 | + } |
| 177 | + |
| 178 | + header( "Content-type: ".$this->mContentType.'; charset='.$this->mCharset ); |
| 179 | + # allow the client to cache this for 24 hours |
| 180 | + header( 'Cache-Control: s-maxage='.$this->mSmaxage.', max-age='.$this->mMaxage ); |
| 181 | + echo $this->getRawText(); |
| 182 | + $wgOut->disable(); |
| 183 | + } |
| 184 | + |
| 185 | + function getRawText() { |
| 186 | + global $wgUser, $wgOut; |
| 187 | + if($this->mGen) { |
| 188 | + $sk = $wgUser->getSkin(); |
| 189 | + $sk->initPage($wgOut); |
| 190 | + if($this->mGen == 'css') { |
| 191 | + return $sk->getUserStylesheet(); |
| 192 | + } else if($this->mGen == 'js') { |
| 193 | + return $sk->getUserJs(); |
| 194 | + } |
| 195 | + } else { |
| 196 | + return $this->getArticleText(); |
| 197 | + } |
| 198 | + } |
| 199 | + |
| 200 | + function getArticleText() { |
| 201 | + if( $this->mTitle ) { |
| 202 | + $text = ''; |
| 203 | + |
| 204 | + // If it's a MediaWiki message we can just hit the message cache |
| 205 | + if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { |
| 206 | + $text = wfMsgForContentNoTrans( $this->mTitle->getDbkey() ); |
| 207 | + } else { |
| 208 | + // Get it from the DB |
| 209 | + $rev = Revision::newFromTitle( $this->mTitle, $this->mOldId ); |
| 210 | + if ( $rev ) { |
| 211 | + $lastmod = wfTimestamp( TS_RFC2822, $rev->getTimestamp() ); |
| 212 | + header( "Last-modified: $lastmod" ); |
| 213 | + $text = $rev->getText(); |
| 214 | + } else |
| 215 | + $text = ''; |
| 216 | + } |
| 217 | + |
| 218 | + return $this->parseArticleText( $text ); |
| 219 | + } |
| 220 | + |
| 221 | + # Bad title or page does not exist |
| 222 | + if( $this->mContentType == 'text/x-wiki' ) { |
| 223 | + # Don't return a 404 response for CSS or JavaScript; |
| 224 | + # 404s aren't generally cached and it would create |
| 225 | + # extra hits when user CSS/JS are on and the user doesn't |
| 226 | + # have the pages. |
| 227 | + header( "HTTP/1.0 404 Not Found" ); |
| 228 | + } |
| 229 | + return ''; |
| 230 | + } |
| 231 | + |
| 232 | + function parseArticleText( $text ) { |
| 233 | + if ( $text === '' ) |
| 234 | + return ''; |
| 235 | + else |
| 236 | + if ( $this->mExpandTemplates ) { |
| 237 | + global $wgTitle; |
| 238 | + |
| 239 | + $parser = new Parser(); |
| 240 | + $parser->Options( new ParserOptions() ); // We don't want this to be user-specific |
| 241 | + $parser->Title( $wgTitle ); |
| 242 | + $parser->OutputType( OT_HTML ); |
| 243 | + |
| 244 | + return $parser->replaceVariables( $text ); |
| 245 | + } else |
| 246 | + return $text; |
| 247 | + } |
| 248 | +} |
| 249 | +?> |
48 | 250 | function MediaWikiCredits() { |
49 | 251 | global $wgVersion; |
50 | 252 | |