79 parent::__construct( $article,
$context );
80 $this->parser = $parser;
81 $this->permissionManager = $permissionManager;
82 $this->revisionLookup = $revisionLookup;
83 $this->restrictionStore = $restrictionStore;
84 $this->userFactory = $userFactory;
107 $response = $request->response();
108 $config = $this->context->getConfig();
110 if ( $this->
getOutput()->checkLastModified(
120 $smaxage = $request->getIntOrNull(
'smaxage' );
121 if ( $smaxage ===
null ) {
123 $contentType ===
'text/css' ||
124 $contentType ===
'application/json' ||
125 $contentType ===
'text/javascript'
138 $response->header( $this->
getOutput()->getVaryHeader() );
142 $privateCache = !$this->permissionManager->isEveryoneAllowed(
'read' ) &&
145 $privateCache = $privateCache || $this->
getUser()->isRegistered();
146 $mode = $privateCache ?
'private' :
'public';
148 'Cache-Control: ' . $mode .
', s-maxage=' . $smaxage .
', max-age=' . $maxage
156 if ( $title->isUserConfigPage() && $contentType !==
'text/x-wiki' ) {
159 $rootPage = strtok( $title->getText(),
'/' );
160 $userFromTitle = $this->userFactory->newFromName( $rootPage, UserRigorOptions::RIGOR_USABLE );
161 if ( !$userFromTitle || !$userFromTitle->isRegistered() ) {
162 $elevated = $this->
getAuthority()->isAllowed(
'editinterface' );
163 $elevatedText = $elevated ?
'by elevated ' :
'';
164 $log = LoggerFactory::getInstance(
"security" );
166 "Unsafe JS/CSS/Json {$elevatedText}load - {user} loaded {title} with {ctype}",
169 'title' => $title->getPrefixedDBkey(),
170 'ctype' => $contentType,
171 'elevated' => $elevated
184 $pageRestrictions = $this->restrictionStore->getRestrictions( $title,
'edit' );
186 $contentType ===
'text/javascript' &&
187 !$title->isUserJsConfigPage() &&
189 !in_array(
'sysop', $pageRestrictions ) &&
190 !in_array(
'editprotected', $pageRestrictions )
193 $log = LoggerFactory::getInstance(
"security" );
194 $log->info(
"Blocked loading unprotected JS {title} for {user}",
197 'title' => $title->getPrefixedDBkey(),
203 $response->header(
'Content-type: ' . $contentType .
'; charset=UTF-8' );
211 if ( $text ===
false && $contentType ===
'text/x-wiki' ) {
212 $response->statusHeader( 404 );
215 if ( !$this->
getHookRunner()->onRawPageViewBeforeOutput( $this, $text ) ) {
216 wfDebug( __METHOD__ .
": RawPageViewBeforeOutput hook broke raw page output." );
236 $rev = $this->revisionLookup->getRevisionByTitle( $title, $this->
getOldId() );
238 $lastMod =
wfTimestamp( TS_RFC2822, $rev->getTimestamp() );
239 $request->response()->header(
"Last-modified: $lastMod" );
243 $slot = $this->
getRequest()->getText(
'slot' );
245 if ( $rev->hasSlot( $slot ) ) {
246 $content = $rev->getContent( $slot );
251 $content = $rev->getContent( SlotRecord::MAIN );
254 if ( $content ===
null ) {
256 } elseif ( !$content instanceof
TextContent && !method_exists( $content,
'getText' ) ) {
260 "Unsupported Media Type",
"The requested page uses the content model `"
261 . $content->getModel() .
"` which is not supported via this interface."
266 $section = $request->getIntOrNull(
'section' );
267 if ( $section !==
null ) {
268 $content = $content->getSection( $section );
271 if ( $content !==
null && $content !==
false ) {
273 $text = $content->getText();
278 if ( $text !==
false && $text !==
'' && $request->getRawVal(
'templates' ) ===
'expand' ) {
279 $text = $this->parser->preprocess(
295 $oldId = $this->
getRequest()->getInt(
'oldid' );
296 $rl = $this->revisionLookup;
297 switch ( $this->
getRequest()->getText(
'direction' ) ) {
299 # output next revision, or nothing if there isn't one
302 $oldRev = $rl->getRevisionById( $oldId );
304 $nextRev = $rl->getNextRevision( $oldRev );
307 $oldId = $nextRev ? $nextRev->getId() : -1;
310 # output previous revision, or nothing if there isn't one
313 # get the current revision so we can get the penultimate one
316 $oldRev = $rl->getRevisionById( $oldId );
318 $prevRev = $rl->getPreviousRevision( $oldRev );
320 $oldId = $prevRev ? $prevRev->getId() : -1;
342 $gen = $this->
getRequest()->getRawVal(
'gen' );
343 if ( $gen ==
'js' ) {
344 $ctype =
'text/javascript';
345 } elseif ( $gen ==
'css' ) {
350 static $allowedCTypes = [
355 'application/x-zope-edit',
358 if (
$ctype ==
'' || !in_array(
$ctype, $allowedCTypes ) ) {
367class_alias( RawAction::class,
'RawAction' );
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfHttpError( $code, $label, $desc)
Provide a simple HTTP error.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Content object implementation for representing flat text.
A class containing constants representing the names of configuration variables.
const CdnMaxAge
Name constant for the CdnMaxAge setting, for use with Config::get()
const ForcedRawSMaxage
Name constant for the ForcedRawSMaxage setting, for use with Config::get()
Legacy class representing an editable page and handling UI for some page actions.
Interface for objects which can provide a MediaWiki context on request.