MediaWiki
master
|
00001 <?php 00033 class RawAction extends FormlessAction { 00034 private $mGen; 00035 00036 public function getName() { 00037 return 'raw'; 00038 } 00039 00040 public function requiresWrite() { 00041 return false; 00042 } 00043 00044 public function requiresUnblock() { 00045 return false; 00046 } 00047 00048 function onView() { 00049 global $wgSquidMaxage, $wgForcedRawSMaxage, $wgJsMimeType; 00050 00051 $this->getOutput()->disable(); 00052 $request = $this->getRequest(); 00053 00054 if ( !$request->checkUrlExtension() ) { 00055 return; 00056 } 00057 00058 if ( $this->getOutput()->checkLastModified( $this->page->getTouched() ) ) { 00059 return; // Client cache fresh and headers sent, nothing more to do. 00060 } 00061 00062 # special case for 'generated' raw things: user css/js 00063 # This is deprecated and will only return empty content 00064 $gen = $request->getVal( 'gen' ); 00065 $smaxage = $request->getIntOrNull( 'smaxage' ); 00066 00067 if ( $gen == 'css' || $gen == 'js' ) { 00068 $this->mGen = $gen; 00069 if ( $smaxage === null ) { 00070 $smaxage = $wgSquidMaxage; 00071 } 00072 } else { 00073 $this->mGen = false; 00074 } 00075 00076 $contentType = $this->getContentType(); 00077 00078 # Force caching for CSS and JS raw content, default: 5 minutes 00079 if ( $smaxage === null ) { 00080 if ( $contentType == 'text/css' || $contentType == $wgJsMimeType ) { 00081 $smaxage = intval( $wgForcedRawSMaxage ); 00082 } else { 00083 $smaxage = 0; 00084 } 00085 } 00086 00087 $maxage = $request->getInt( 'maxage', $wgSquidMaxage ); 00088 00089 $response = $request->response(); 00090 00091 $response->header( 'Content-type: ' . $contentType . '; charset=UTF-8' ); 00092 # Output may contain user-specific data; 00093 # vary generated content for open sessions on private wikis 00094 $privateCache = !User::groupHasPermission( '*', 'read' ) && ( $smaxage == 0 || session_id() != '' ); 00095 # allow the client to cache this for 24 hours 00096 $mode = $privateCache ? 'private' : 'public'; 00097 $response->header( 'Cache-Control: ' . $mode . ', s-maxage=' . $smaxage . ', max-age=' . $maxage ); 00098 00099 $text = $this->getRawText(); 00100 00101 if ( $text === false && $contentType == 'text/x-wiki' ) { 00102 # Don't return a 404 response for CSS or JavaScript; 00103 # 404s aren't generally cached and it would create 00104 # extra hits when user CSS/JS are on and the user doesn't 00105 # have the pages. 00106 $response->header( 'HTTP/1.x 404 Not Found' ); 00107 } 00108 00109 if ( !wfRunHooks( 'RawPageViewBeforeOutput', array( &$this, &$text ) ) ) { 00110 wfDebug( __METHOD__ . ": RawPageViewBeforeOutput hook broke raw page output.\n" ); 00111 } 00112 00113 echo $text; 00114 } 00115 00122 public function getRawText() { 00123 global $wgParser; 00124 00125 # No longer used 00126 if( $this->mGen ) { 00127 return ''; 00128 } 00129 00130 $text = false; 00131 $title = $this->getTitle(); 00132 $request = $this->getRequest(); 00133 00134 // If it's a MediaWiki message we can just hit the message cache 00135 if ( $request->getBool( 'usemsgcache' ) && $title->getNamespace() == NS_MEDIAWIKI ) { 00136 // The first "true" is to use the database, the second is to use the content langue 00137 // and the last one is to specify the message key already contains the language in it ("/de", etc.) 00138 $text = MessageCache::singleton()->get( $title->getDBkey(), true, true, true ); 00139 // If the message doesn't exist, return a blank 00140 if ( $text === false ) { 00141 $text = ''; 00142 } 00143 } else { 00144 // Get it from the DB 00145 $rev = Revision::newFromTitle( $title, $this->getOldId() ); 00146 if ( $rev ) { 00147 $lastmod = wfTimestamp( TS_RFC2822, $rev->getTimestamp() ); 00148 $request->response()->header( "Last-modified: $lastmod" ); 00149 00150 // Public-only due to cache headers 00151 $content = $rev->getContent(); 00152 00153 if ( $content === null ) { 00154 // revision not found (or suppressed) 00155 $text = false; 00156 } elseif ( !$content instanceof TextContent ) { 00157 // non-text content 00158 wfHttpError( 415, "Unsupported Media Type", "The requested page uses the content model `" 00159 . $content->getModel() . "` which is not supported via this interface." ); 00160 die(); 00161 } else { 00162 // want a section? 00163 $section = $request->getIntOrNull( 'section' ); 00164 if ( $section !== null ) { 00165 $content = $content->getSection( $section ); 00166 } 00167 00168 if ( $content === null || $content === false ) { 00169 // section not found (or section not supported, e.g. for JS and CSS) 00170 $text = false; 00171 } else { 00172 $text = $content->getNativeData(); 00173 } 00174 } 00175 } 00176 } 00177 00178 if ( $text !== false && $text !== '' && $request->getVal( 'templates' ) === 'expand' ) { 00179 $text = $wgParser->preprocess( $text, $title, ParserOptions::newFromContext( $this->getContext() ) ); 00180 } 00181 00182 return $text; 00183 } 00184 00190 public function getOldId() { 00191 $oldid = $this->getRequest()->getInt( 'oldid' ); 00192 switch ( $this->getRequest()->getText( 'direction' ) ) { 00193 case 'next': 00194 # output next revision, or nothing if there isn't one 00195 if( $oldid ) { 00196 $oldid = $this->getTitle()->getNextRevisionId( $oldid ); 00197 } 00198 $oldid = $oldid ? $oldid : -1; 00199 break; 00200 case 'prev': 00201 # output previous revision, or nothing if there isn't one 00202 if( !$oldid ) { 00203 # get the current revision so we can get the penultimate one 00204 $oldid = $this->page->getLatest(); 00205 } 00206 $prev = $this->getTitle()->getPreviousRevisionId( $oldid ); 00207 $oldid = $prev ? $prev : -1 ; 00208 break; 00209 case 'cur': 00210 $oldid = 0; 00211 break; 00212 } 00213 return $oldid; 00214 } 00215 00221 public function getContentType() { 00222 global $wgJsMimeType; 00223 00224 $ctype = $this->getRequest()->getVal( 'ctype' ); 00225 00226 if ( $ctype == '' ) { 00227 $gen = $this->getRequest()->getVal( 'gen' ); 00228 if ( $gen == 'js' ) { 00229 $ctype = $wgJsMimeType; 00230 } elseif ( $gen == 'css' ) { 00231 $ctype = 'text/css'; 00232 } 00233 } 00234 00235 $allowedCTypes = array( 'text/x-wiki', $wgJsMimeType, 'text/css', 'application/x-zope-edit' ); 00236 if ( $ctype == '' || !in_array( $ctype, $allowedCTypes ) ) { 00237 $ctype = 'text/x-wiki'; 00238 } 00239 00240 return $ctype; 00241 } 00242 } 00243 00249 class RawPage extends RawAction { 00250 public $mOldId; 00251 00252 function __construct( Page $page, $request = false ) { 00253 wfDeprecated( __CLASS__, '1.19' ); 00254 parent::__construct( $page ); 00255 00256 if ( $request !== false ) { 00257 $context = new DerivativeContext( $this->getContext() ); 00258 $context->setRequest( $request ); 00259 $this->context = $context; 00260 } 00261 } 00262 00263 public function view() { 00264 $this->onView(); 00265 } 00266 00267 public function getOldId() { 00268 # Some extensions like to set $mOldId 00269 if ( $this->mOldId !== null ) { 00270 return $this->mOldId; 00271 } 00272 return parent::getOldId(); 00273 } 00274 }