MediaWiki master
WebInstallerOutput.php
Go to the documentation of this file.
1<?php
2
9namespace MediaWiki\Installer;
10
11use LogicException;
18
32
38 public $parent;
39
44 private $contents = '';
45
50 private $headerDone = false;
51
56
57 public function __construct( WebInstaller $parent ) {
58 $this->parent = $parent;
59 }
60
64 public function addHTML( $html ) {
65 $this->contents .= $html;
66 $this->flush();
67 }
68
73 public function addWikiTextAsInterface( $text ) {
74 $this->addHTML( $this->parent->parse( $text ) );
75 }
76
80 public function addHTMLNoFlush( $html ) {
81 $this->contents .= $html;
82 }
83
87 public function redirect( $url ) {
88 if ( $this->headerDone ) {
89 throw new LogicException( __METHOD__ . ' called after sending headers' );
90 }
91 $this->redirectTarget = $url;
92 }
93
94 public function output() {
95 $this->flush();
96
97 if ( !$this->redirectTarget ) {
98 $this->outputFooter();
99 }
100 }
101
107 public function getCSS() {
108 $resourceLoader = MediaWikiServices::getInstance()->getResourceLoader();
109
110 $rlContext = new RL\Context( $resourceLoader, new FauxRequest( [
111 'debug' => 'true',
112 'lang' => $this->getLanguage()->getCode(),
113 'only' => 'styles',
114 ] ) );
115
116 $module = new RL\SkinModule( [
117 'features' => [
118 'elements',
119 'interface-message-box'
120 ],
121 'styles' => [
122 'mw-config/config.css',
123 ],
124 ] );
125 $module->setConfig( $resourceLoader->getConfig() );
126
127 // Based on MediaWiki\ResourceLoader\FileModule::getStyles, without the DB query
128 $styles = ResourceLoader::makeCombinedStyles(
129 $module->readStyleFiles(
130 $module->getStyleFiles( $rlContext ),
131 $rlContext
132 ) );
133
134 return implode( "\n", $styles );
135 }
136
142 private function getCssUrl() {
143 return Html::linkedStyle( $this->parent->getUrl( [ 'css' => 1 ] ) );
144 }
145
146 public function flush() {
147 if ( !$this->headerDone ) {
148 $this->outputHeader();
149 }
150 if ( !$this->redirectTarget && strlen( $this->contents ) ) {
151 echo $this->contents;
152 flush();
153 $this->contents = '';
154 }
155 }
156
161 private function getLanguage() {
162 global $wgLang;
163
164 return is_object( $wgLang ) ? $wgLang
165 : MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( 'en' );
166 }
167
171 public function getHeadAttribs() {
172 return [
173 'dir' => $this->getLanguage()->getDir(),
174 'lang' => $this->getLanguage()->getHtmlCode(),
175 ];
176 }
177
183 public function headerDone() {
184 return $this->headerDone;
185 }
186
187 public function outputHeader() {
188 $this->headerDone = true;
189 $this->parent->request->response()->header( 'Content-Type: text/html; charset=utf-8' );
190 $this->parent->request->response()->header( 'X-Frame-Options: DENY' );
191
192 $cspPolicy = "default-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none';" .
193 " script-src 'self' 'nonce-" . $this->getCSPNonce() . "';" .
194 " img-src 'self'; frame-src 'self'; base-uri 'none'";
195
196 $this->parent->request->response()->header( 'Content-Security-Policy: ' . $cspPolicy );
197
198 if ( $this->redirectTarget ) {
199 $this->parent->request->response()->header( 'Location: ' . $this->redirectTarget );
200
201 return;
202 }
203?>
204<?php echo Html::htmlHeader( $this->getHeadAttribs() ); ?>
205
206<head>
207 <meta name="robots" content="noindex, nofollow" />
208 <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
209 <title><?php $this->outputTitle(); ?></title>
210 <?php echo $this->getCodex() . "\n"; ?>
211 <?php echo $this->getCssUrl() . "\n"; ?>
212 <?php echo $this->getJQuery() . "\n"; ?>
213 <?php echo Html::linkedScript( 'config.js' ) . "\n"; ?>
214</head>
215
216<?php echo Html::openElement( 'body', [ 'class' => $this->getLanguage()->getDir() ] ) . "\n"; ?>
217<div id="mw-page-base"></div>
218<div id="mw-head-base"></div>
219<div id="content" class="mw-body" role="main">
220<div id="bodyContent" class="mw-body-content">
221
222<h1><?php $this->outputTitle(); ?></h1>
223<?php
224 }
225
226 public function outputFooter() {
227?>
228
229</div></div>
230
231<aside id="mw-panel">
232 <div class="portal" id="p-logo">
233 <a href="https://www.mediawiki.org/" title="Main Page"></a>
234 </div>
235<?php
236 // @phpcs:disable Generic.WhiteSpace.ScopeIndent.IncorrectExact
237 $message = wfMessage( 'config-sidebar' )->plain();
238 // Section 1: External links
239 // @todo FIXME: Migrate to plain link label messages (T227297).
240 foreach ( explode( '----', $message ) as $section ) {
241 echo '<div class="portal"><div class="body">';
242 echo $this->parent->parse( $section, true );
243 echo '</div></div>';
244 }
245 // Section 2: Installer pages
246 echo '<div class="portal"><div class="body"><ul>';
247 foreach ( [
248 'config-sidebar-relnotes' => 'ReleaseNotes',
249 'config-sidebar-license' => 'Copying',
250 'config-sidebar-upgrade' => 'UpgradeDoc',
251 ] as $msgKey => $pageName ) {
252 echo $this->parent->makeLinkItem(
253 $this->parent->getDocUrl( $pageName ),
254 wfMessage( $msgKey )->text()
255 );
256 }
257 echo '</ul></div></div>';
258 // @phpcs:enable
259?>
260</aside>
261
262<?php
263 echo Html::closeElement( 'body' ) . Html::closeElement( 'html' );
264 }
265
266 public function outputTitle() {
267 echo wfMessage( 'config-title', MW_VERSION )->escaped();
268 }
269
273 public function getJQuery() {
274 return Html::linkedScript( "../resources/lib/jquery/jquery.js" );
275 }
276
280 public function getCodex() {
281 return Html::linkedStyle( "../resources/lib/codex/codex.style.css" );
282 }
283
290 public function getCSPNonce() {
291 static $nonce;
292 if ( $nonce === null ) {
293 // Spec says at least 16 bytes. Do 18 so it encodes evenly in base64
294 $nonce = base64_encode( random_bytes( 18 ) );
295 }
296 return $nonce;
297 }
298}
const MW_VERSION
The running version of MediaWiki.
Definition Defines.php:23
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(MW_ENTRY_POINT==='index') if(!defined( 'MW_NO_SESSION') &&MW_ENTRY_POINT !=='cli' $wgLang
Definition Setup.php:551
This class is a collection of static functions that serve two purposes:
Definition Html.php:43
Output class modelled on OutputPage.
getCSPNonce()
Get the nonce for use with inline scripts.
headerDone()
Get whether the header has been output.
getCSS()
Get the stylesheet of the MediaWiki skin.
WebInstaller $parent
The WebInstaller object this WebInstallerOutput is used by.
Class for the core installer web interface.
Base class for language-specific code.
Definition Language.php:70
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
WebRequest clone which takes values from a provided array.
Context object that contains information about the state of a specific ResourceLoader web request.
Definition Context.php:32
ResourceLoader is a loading system for JavaScript and CSS resources.
Module for skin stylesheets.