Index: trunk/phase3/RELEASE-NOTES-1.19 |
— | — | @@ -86,8 +86,6 @@ |
87 | 87 | |
88 | 88 | === API changes in 1.19 === |
89 | 89 | * BREAKING CHANGE: action=watch now requires POST and token. |
90 | | -* BREAKING CHANGE: index.php?action=raw has been removed. You should be using |
91 | | - load.php or api.php for CSS/JS or raw page text requests, respectively. |
92 | 90 | * (bug 27790) add query type for querymodules to action=paraminfo |
93 | 91 | * (bug 28963) add langbacklinks module to api |
94 | 92 | * (bug 27593) API: add error message when sha1/sha1base36 is invalid |
Index: trunk/phase3/includes/GlobalFunctions.php |
— | — | @@ -318,7 +318,7 @@ |
319 | 319 | * Controlling globals: |
320 | 320 | * $wgDebugLogFile - points to the log file |
321 | 321 | * $wgProfileOnly - if set, normal debug messages will not be recorded. |
322 | | - * $wgDebugRawPage - if false, 'load.php' hits will not result in debug output. |
| 322 | + * $wgDebugRawPage - if false, 'action=raw' hits will not result in debug output. |
323 | 323 | * $wgDebugComments - if on, some debug items may appear in comments in the HTML output. |
324 | 324 | * |
325 | 325 | * @param $text String |
— | — | @@ -363,9 +363,12 @@ |
364 | 364 | if ( $cache !== null ) { |
365 | 365 | return $cache; |
366 | 366 | } |
367 | | - |
368 | | - if( isset( $_SERVER['SCRIPT_NAME'] ) |
369 | | - && substr( $_SERVER['SCRIPT_NAME'], -8 ) == 'load.php' ) |
| 367 | + # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet |
| 368 | + if ( ( isset( $_GET['action'] ) && $_GET['action'] == 'raw' ) |
| 369 | + || ( |
| 370 | + isset( $_SERVER['SCRIPT_NAME'] ) |
| 371 | + && substr( $_SERVER['SCRIPT_NAME'], -8 ) == 'load.php' |
| 372 | + ) ) |
370 | 373 | { |
371 | 374 | $cache = true; |
372 | 375 | } else { |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -175,6 +175,7 @@ |
176 | 176 | 'ProtectionForm' => 'includes/ProtectionForm.php', |
177 | 177 | 'QueryPage' => 'includes/QueryPage.php', |
178 | 178 | 'QuickTemplate' => 'includes/SkinTemplate.php', |
| 179 | + 'RawPage' => 'includes/RawPage.php', |
179 | 180 | 'RCCacheEntry' => 'includes/ChangesList.php', |
180 | 181 | 'RdfMetaData' => 'includes/Metadata.php', |
181 | 182 | 'ReadOnlyError' => 'includes/Exception.php', |
Index: trunk/phase3/includes/Wiki.php |
— | — | @@ -418,6 +418,12 @@ |
419 | 419 | $this->context->output->setSquidMaxage( $wgSquidMaxage ); |
420 | 420 | $article->view(); |
421 | 421 | break; |
| 422 | + case 'raw': // includes JS/CSS |
| 423 | + wfProfileIn( __METHOD__ . '-raw' ); |
| 424 | + $raw = new RawPage( $article ); |
| 425 | + $raw->view(); |
| 426 | + wfProfileOut( __METHOD__ . '-raw' ); |
| 427 | + break; |
422 | 428 | case 'delete': |
423 | 429 | case 'revert': |
424 | 430 | case 'rollback': |
Index: trunk/phase3/includes/RawPage.php |
— | — | @@ -0,0 +1,228 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Raw page text accessor |
| 5 | + * |
| 6 | + * Copyright © 2004 Gabriel Wicke <wicke@wikidev.net> |
| 7 | + * http://wikidev.net/ |
| 8 | + * |
| 9 | + * Based on HistoryPage and SpecialExport |
| 10 | + * |
| 11 | + * License: GPL (http://www.gnu.org/copyleft/gpl.html) |
| 12 | + * |
| 13 | + * @author Gabriel Wicke <wicke@wikidev.net> |
| 14 | + * @file |
| 15 | + */ |
| 16 | + |
| 17 | +/** |
| 18 | + * A simple method to retrieve the plain source of an article, |
| 19 | + * using "action=raw" in the GET request string. |
| 20 | + */ |
| 21 | +class RawPage { |
| 22 | + var $mArticle, $mTitle, $mRequest; |
| 23 | + var $mOldId, $mGen, $mCharset, $mSection; |
| 24 | + var $mSmaxage, $mMaxage; |
| 25 | + var $mContentType, $mExpandTemplates; |
| 26 | + |
| 27 | + function __construct( Article $article, $request = false ) { |
| 28 | + global $wgRequest, $wgSquidMaxage, $wgJsMimeType, $wgGroupPermissions; |
| 29 | + |
| 30 | + $allowedCTypes = array( 'text/x-wiki', $wgJsMimeType, 'text/css', 'application/x-zope-edit' ); |
| 31 | + $this->mArticle = $article; |
| 32 | + $this->mTitle = $article->mTitle; |
| 33 | + |
| 34 | + if( $request === false ) { |
| 35 | + $this->mRequest = $wgRequest; |
| 36 | + } else { |
| 37 | + $this->mRequest = $request; |
| 38 | + } |
| 39 | + |
| 40 | + $ctype = $this->mRequest->getVal( 'ctype' ); |
| 41 | + $smaxage = $this->mRequest->getIntOrNull( 'smaxage' ); |
| 42 | + $maxage = $this->mRequest->getInt( 'maxage', $wgSquidMaxage ); |
| 43 | + |
| 44 | + $this->mExpandTemplates = $this->mRequest->getVal( 'templates' ) === 'expand'; |
| 45 | + $this->mUseMessageCache = $this->mRequest->getBool( 'usemsgcache' ); |
| 46 | + |
| 47 | + $this->mSection = $this->mRequest->getIntOrNull( 'section' ); |
| 48 | + |
| 49 | + $oldid = $this->mRequest->getInt( 'oldid' ); |
| 50 | + |
| 51 | + switch( $wgRequest->getText( 'direction' ) ) { |
| 52 | + case 'next': |
| 53 | + # output next revision, or nothing if there isn't one |
| 54 | + if( $oldid ) { |
| 55 | + $oldid = $this->mTitle->getNextRevisionId( $oldid ); |
| 56 | + } |
| 57 | + $oldid = $oldid ? $oldid : -1; |
| 58 | + break; |
| 59 | + case 'prev': |
| 60 | + # output previous revision, or nothing if there isn't one |
| 61 | + if( !$oldid ) { |
| 62 | + # get the current revision so we can get the penultimate one |
| 63 | + $this->mArticle->getTouched(); |
| 64 | + $oldid = $this->mArticle->mLatest; |
| 65 | + } |
| 66 | + $prev = $this->mTitle->getPreviousRevisionId( $oldid ); |
| 67 | + $oldid = $prev ? $prev : -1 ; |
| 68 | + break; |
| 69 | + case 'cur': |
| 70 | + $oldid = 0; |
| 71 | + break; |
| 72 | + } |
| 73 | + $this->mOldId = $oldid; |
| 74 | + |
| 75 | + # special case for 'generated' raw things: user css/js |
| 76 | + $gen = $this->mRequest->getVal( 'gen' ); |
| 77 | + |
| 78 | + if( $gen == 'css' ) { |
| 79 | + $this->mGen = $gen; |
| 80 | + if( is_null( $smaxage ) ) { |
| 81 | + $smaxage = $wgSquidMaxage; |
| 82 | + } |
| 83 | + if( $ctype == '' ) { |
| 84 | + $ctype = 'text/css'; |
| 85 | + } |
| 86 | + } elseif( $gen == 'js' ) { |
| 87 | + $this->mGen = $gen; |
| 88 | + if( is_null( $smaxage ) ) $smaxage = $wgSquidMaxage; |
| 89 | + if($ctype == '') $ctype = $wgJsMimeType; |
| 90 | + } else { |
| 91 | + $this->mGen = false; |
| 92 | + } |
| 93 | + $this->mCharset = 'UTF-8'; |
| 94 | + |
| 95 | + # Force caching for CSS and JS raw content, default: 5 minutes |
| 96 | + if( is_null( $smaxage ) && ( $ctype == 'text/css' || $ctype == $wgJsMimeType ) ) { |
| 97 | + global $wgForcedRawSMaxage; |
| 98 | + $this->mSmaxage = intval( $wgForcedRawSMaxage ); |
| 99 | + } else { |
| 100 | + $this->mSmaxage = intval( $smaxage ); |
| 101 | + } |
| 102 | + $this->mMaxage = $maxage; |
| 103 | + |
| 104 | + # Output may contain user-specific data; |
| 105 | + # vary generated content for open sessions and private wikis |
| 106 | + if( $this->mGen || !$wgGroupPermissions['*']['read'] ) { |
| 107 | + $this->mPrivateCache = $this->mSmaxage == 0 || session_id() != ''; |
| 108 | + } else { |
| 109 | + $this->mPrivateCache = false; |
| 110 | + } |
| 111 | + |
| 112 | + if( $ctype == '' || !in_array( $ctype, $allowedCTypes ) ) { |
| 113 | + $this->mContentType = 'text/x-wiki'; |
| 114 | + } else { |
| 115 | + $this->mContentType = $ctype; |
| 116 | + } |
| 117 | + } |
| 118 | + |
| 119 | + function view() { |
| 120 | + global $wgOut, $wgRequest; |
| 121 | + |
| 122 | + if( !$wgRequest->checkUrlExtension() ) { |
| 123 | + $wgOut->disable(); |
| 124 | + return; |
| 125 | + } |
| 126 | + |
| 127 | + header( 'Content-type: ' . $this->mContentType . '; charset=' . $this->mCharset ); |
| 128 | + # allow the client to cache this for 24 hours |
| 129 | + $mode = $this->mPrivateCache ? 'private' : 'public'; |
| 130 | + header( 'Cache-Control: ' . $mode . ', s-maxage=' . $this->mSmaxage . ', max-age=' . $this->mMaxage ); |
| 131 | + |
| 132 | + global $wgUseFileCache; |
| 133 | + if( $wgUseFileCache && HTMLFileCache::useFileCache() ) { |
| 134 | + $cache = new HTMLFileCache( $this->mTitle, 'raw' ); |
| 135 | + if( $cache->isFileCacheGood( /* Assume up to date */ ) ) { |
| 136 | + $cache->loadFromFileCache(); |
| 137 | + $wgOut->disable(); |
| 138 | + return; |
| 139 | + } else { |
| 140 | + ob_start( array( &$cache, 'saveToFileCache' ) ); |
| 141 | + } |
| 142 | + } |
| 143 | + |
| 144 | + $text = $this->getRawText(); |
| 145 | + |
| 146 | + if( !wfRunHooks( 'RawPageViewBeforeOutput', array( &$this, &$text ) ) ) { |
| 147 | + wfDebug( __METHOD__ . ": RawPageViewBeforeOutput hook broke raw page output.\n" ); |
| 148 | + } |
| 149 | + |
| 150 | + echo $text; |
| 151 | + $wgOut->disable(); |
| 152 | + } |
| 153 | + |
| 154 | + function getRawText() { |
| 155 | + global $wgUser, $wgOut; |
| 156 | + if( $this->mGen ) { |
| 157 | + $sk = $wgUser->getSkin(); |
| 158 | + if( !StubObject::isRealObject( $wgOut ) ) { |
| 159 | + $wgOut->_unstub( 2 ); |
| 160 | + } |
| 161 | + $sk->initPage( $wgOut ); |
| 162 | + if( $this->mGen == 'css' ) { |
| 163 | + return $sk->generateUserStylesheet(); |
| 164 | + } else if( $this->mGen == 'js' ) { |
| 165 | + return $sk->generateUserJs(); |
| 166 | + } |
| 167 | + } else { |
| 168 | + return $this->getArticleText(); |
| 169 | + } |
| 170 | + } |
| 171 | + |
| 172 | + function getArticleText() { |
| 173 | + $found = false; |
| 174 | + $text = ''; |
| 175 | + if( $this->mTitle ) { |
| 176 | + // If it's a MediaWiki message we can just hit the message cache |
| 177 | + if( $this->mUseMessageCache && $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { |
| 178 | + $key = $this->mTitle->getDBkey(); |
| 179 | + $msg = wfMessage( $key )->inContentLanguage(); |
| 180 | + # If the message doesn't exist, return a blank |
| 181 | + $text = !$msg->exists() ? '' : $msg->plain(); |
| 182 | + $found = true; |
| 183 | + } else { |
| 184 | + // Get it from the DB |
| 185 | + $rev = Revision::newFromTitle( $this->mTitle, $this->mOldId ); |
| 186 | + if( $rev ) { |
| 187 | + $lastmod = wfTimestamp( TS_RFC2822, $rev->getTimestamp() ); |
| 188 | + header( "Last-modified: $lastmod" ); |
| 189 | + |
| 190 | + if( !is_null( $this->mSection ) ) { |
| 191 | + global $wgParser; |
| 192 | + $text = $wgParser->getSection( $rev->getText(), $this->mSection ); |
| 193 | + } else { |
| 194 | + $text = $rev->getText(); |
| 195 | + } |
| 196 | + $found = true; |
| 197 | + } |
| 198 | + } |
| 199 | + } |
| 200 | + |
| 201 | + # Bad title or page does not exist |
| 202 | + if( !$found && $this->mContentType == 'text/x-wiki' ) { |
| 203 | + # Don't return a 404 response for CSS or JavaScript; |
| 204 | + # 404s aren't generally cached and it would create |
| 205 | + # extra hits when user CSS/JS are on and the user doesn't |
| 206 | + # have the pages. |
| 207 | + header( 'HTTP/1.0 404 Not Found' ); |
| 208 | + } |
| 209 | + |
| 210 | + return $this->parseArticleText( $text ); |
| 211 | + } |
| 212 | + |
| 213 | + /** |
| 214 | + * @param $text |
| 215 | + * @return string |
| 216 | + */ |
| 217 | + function parseArticleText( $text ) { |
| 218 | + if( $text === '' ) { |
| 219 | + return ''; |
| 220 | + } else { |
| 221 | + if( $this->mExpandTemplates ) { |
| 222 | + global $wgParser; |
| 223 | + return $wgParser->preprocess( $text, $this->mTitle, new ParserOptions() ); |
| 224 | + } else { |
| 225 | + return $text; |
| 226 | + } |
| 227 | + } |
| 228 | + } |
| 229 | +} |
Property changes on: trunk/phase3/includes/RawPage.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 230 | + native |
Added: svn:keywords |
2 | 231 | + Author Date Id Revision |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -3824,8 +3824,9 @@ |
3825 | 3825 | $wgDebugRedirects = false; |
3826 | 3826 | |
3827 | 3827 | /** |
3828 | | - * If true, log debugging data from and load.php. |
3829 | | - * This is normally false to avoid overlapping debug entries |
| 3828 | + * If true, log debugging data from action=raw and load.php. |
| 3829 | + * This is normally false to avoid overlapping debug entries due to gen=css and |
| 3830 | + * gen=js requests. |
3830 | 3831 | */ |
3831 | 3832 | $wgDebugRawPage = false; |
3832 | 3833 | |