MediaWiki  REL1_20
RawAction.php
Go to the documentation of this file.
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 $wgGroupPermissions, $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 = !$wgGroupPermissions['*']['read'] && ( $smaxage == 0 || session_id() != '' );
00095                 // Bug 53032 - make this private if user is logged in,
00096                 // so we don't accidentally cache cookies
00097                 $privateCache = $privateCache ?: $this->getUser()->isLoggedIn();
00098                 # allow the client to cache this for 24 hours
00099                 $mode = $privateCache ? 'private' : 'public';
00100                 $response->header( 'Cache-Control: ' . $mode . ', s-maxage=' . $smaxage . ', max-age=' . $maxage );
00101 
00102                 $text = $this->getRawText();
00103 
00104                 if ( $text === false && $contentType == 'text/x-wiki' ) {
00105                         # Don't return a 404 response for CSS or JavaScript;
00106                         # 404s aren't generally cached and it would create
00107                         # extra hits when user CSS/JS are on and the user doesn't
00108                         # have the pages.
00109                         $response->header( 'HTTP/1.x 404 Not Found' );
00110                 }
00111 
00112                 if ( !wfRunHooks( 'RawPageViewBeforeOutput', array( &$this, &$text ) ) ) {
00113                         wfDebug( __METHOD__ . ": RawPageViewBeforeOutput hook broke raw page output.\n" );
00114                 }
00115 
00116                 echo $text;
00117         }
00118 
00125         public function getRawText() {
00126                 global $wgParser;
00127 
00128                 # No longer used
00129                 if( $this->mGen ) {
00130                         return '';
00131                 }
00132 
00133                 $text = false;
00134                 $title = $this->getTitle();
00135                 $request = $this->getRequest();
00136 
00137                 // If it's a MediaWiki message we can just hit the message cache
00138                 if ( $request->getBool( 'usemsgcache' ) && $title->getNamespace() == NS_MEDIAWIKI ) {
00139                         // The first "true" is to use the database, the second is to use the content langue
00140                         // and the last one is to specify the message key already contains the language in it ("/de", etc.)
00141                         $text = MessageCache::singleton()->get( $title->getDBkey(), true, true, true );
00142                         // If the message doesn't exist, return a blank
00143                         if ( $text === false ) {
00144                                 $text = '';
00145                         }
00146                 } else {
00147                         // Get it from the DB
00148                         $rev = Revision::newFromTitle( $title, $this->getOldId() );
00149                         if ( $rev ) {
00150                                 $lastmod = wfTimestamp( TS_RFC2822, $rev->getTimestamp() );
00151                                 $request->response()->header( "Last-modified: $lastmod" );
00152 
00153                                 // Public-only due to cache headers
00154                                 $text = $rev->getText();
00155                                 $section = $request->getIntOrNull( 'section' );
00156                                 if ( $section !== null ) {
00157                                         $text = $wgParser->getSection( $text, $section );
00158                                 }
00159                         }
00160                 }
00161 
00162                 if ( $text !== false && $text !== '' && $request->getVal( 'templates' ) === 'expand' ) {
00163                         $text = $wgParser->preprocess( $text, $title, ParserOptions::newFromContext( $this->getContext() ) );
00164                 }
00165 
00166                 return $text;
00167         }
00168 
00174         public function getOldId() {
00175                 $oldid = $this->getRequest()->getInt( 'oldid' );
00176                 switch ( $this->getRequest()->getText( 'direction' ) ) {
00177                         case 'next':
00178                                 # output next revision, or nothing if there isn't one
00179                                 if( $oldid ) {
00180                                         $oldid = $this->getTitle()->getNextRevisionId( $oldid );
00181                                 }
00182                                 $oldid = $oldid ? $oldid : -1;
00183                                 break;
00184                         case 'prev':
00185                                 # output previous revision, or nothing if there isn't one
00186                                 if( !$oldid ) {
00187                                         # get the current revision so we can get the penultimate one
00188                                         $oldid = $this->page->getLatest();
00189                                 }
00190                                 $prev = $this->getTitle()->getPreviousRevisionId( $oldid );
00191                                 $oldid = $prev ? $prev : -1 ;
00192                                 break;
00193                         case 'cur':
00194                                 $oldid = 0;
00195                                 break;
00196                 }
00197                 return $oldid;
00198         }
00199 
00205         public function getContentType() {
00206                 global $wgJsMimeType;
00207 
00208                 $ctype = $this->getRequest()->getVal( 'ctype' );
00209 
00210                 if ( $ctype == '' ) {
00211                         $gen = $this->getRequest()->getVal( 'gen' );
00212                         if ( $gen == 'js' ) {
00213                                 $ctype = $wgJsMimeType;
00214                         } elseif ( $gen == 'css' ) {
00215                                 $ctype = 'text/css';
00216                         }
00217                 }
00218 
00219                 $allowedCTypes = array( 'text/x-wiki', $wgJsMimeType, 'text/css', 'application/x-zope-edit' );
00220                 if ( $ctype == '' || !in_array( $ctype, $allowedCTypes ) ) {
00221                         $ctype = 'text/x-wiki';
00222                 }
00223 
00224                 return $ctype;
00225         }
00226 }
00227 
00233 class RawPage extends RawAction {
00234         public $mOldId;
00235 
00236         function __construct( Page $page, $request = false ) {
00237                 wfDeprecated( __CLASS__, '1.19' );
00238                 parent::__construct( $page );
00239 
00240                 if ( $request !== false ) {
00241                         $context = new DerivativeContext( $this->getContext() );
00242                         $context->setRequest( $request );
00243                         $this->context = $context;
00244                 }
00245         }
00246 
00247         public function view() {
00248                 $this->onView();
00249         }
00250 
00251         public function getOldId() {
00252                 # Some extensions like to set $mOldId
00253                 if ( $this->mOldId !== null ) {
00254                         return $this->mOldId;
00255                 }
00256                 return parent::getOldId();
00257         }
00258 }