Completed
Branch master (939199)
by
unknown
39:35
created

includes/installer/WebInstallerOutput.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Output handler for the web installer.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License along
16
 * with this program; if not, write to the Free Software Foundation, Inc.,
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
 * http://www.gnu.org/copyleft/gpl.html
19
 *
20
 * @file
21
 * @ingroup Deployment
22
 */
23
24
/**
25
 * Output class modelled on OutputPage.
26
 *
27
 * I've opted to use a distinct class rather than derive from OutputPage here in
28
 * the interests of separation of concerns: if we used a subclass, there would be
29
 * quite a lot of things you could do in OutputPage that would break the installer,
30
 * that wouldn't be immediately obvious.
31
 *
32
 * @ingroup Deployment
33
 * @since 1.17
34
 */
35
class WebInstallerOutput {
36
37
	/**
38
	 * The WebInstaller object this WebInstallerOutput is used by.
39
	 *
40
	 * @var WebInstaller
41
	 */
42
	public $parent;
43
44
	/**
45
	 * Buffered contents that haven't been output yet
46
	 * @var string
47
	 */
48
	private $contents = '';
49
50
	/**
51
	 * Has the header (or short header) been output?
52
	 * @var bool
53
	 */
54
	private $headerDone = false;
55
56
	/**
57
	 * @var string
58
	 */
59
	public $redirectTarget;
60
61
	/**
62
	 * Does the current page need to allow being used as a frame?
63
	 * If not, X-Frame-Options will be output to forbid it.
64
	 *
65
	 * @var bool
66
	 */
67
	public $allowFrames = false;
68
69
	/**
70
	 * Whether to use the limited header (used during CC license callbacks)
71
	 * @var bool
72
	 */
73
	private $useShortHeader = false;
74
75
	/**
76
	 * @param WebInstaller $parent
77
	 */
78
	public function __construct( WebInstaller $parent ) {
79
		$this->parent = $parent;
80
	}
81
82
	/**
83
	 * @param string $html
84
	 */
85
	public function addHTML( $html ) {
86
		$this->contents .= $html;
87
		$this->flush();
88
	}
89
90
	/**
91
	 * @param string $text
92
	 */
93
	public function addWikiText( $text ) {
94
		$this->addHTML( $this->parent->parse( $text ) );
95
	}
96
97
	/**
98
	 * @param string $html
99
	 */
100
	public function addHTMLNoFlush( $html ) {
101
		$this->contents .= $html;
102
	}
103
104
	/**
105
	 * @param string $url
106
	 *
107
	 * @throws MWException
108
	 */
109
	public function redirect( $url ) {
110
		if ( $this->headerDone ) {
111
			throw new MWException( __METHOD__ . ' called after sending headers' );
112
		}
113
		$this->redirectTarget = $url;
114
	}
115
116
	public function output() {
117
		$this->flush();
118
119
		if ( !$this->redirectTarget ) {
120
			$this->outputFooter();
121
		}
122
	}
123
124
	/**
125
	 * Get the stylesheet of the MediaWiki skin.
126
	 *
127
	 * @return string
128
	 */
129
	public function getCSS() {
130
		global $wgStyleDirectory;
131
132
		$moduleNames = [
133
			// See SkinTemplate::setupSkinUserCss
134
			'mediawiki.legacy.shared',
135
			// See Vector::setupSkinUserCss
136
			'mediawiki.skinning.interface',
137
		];
138
139
		$resourceLoader = new ResourceLoader();
140
141
		if ( file_exists( "$wgStyleDirectory/Vector/skin.json" ) ) {
142
			// Force loading Vector skin if available as a fallback skin
143
			// for whatever ResourceLoader wants to have as the default.
144
			$registry = new ExtensionRegistry();
145
			$data = $registry->readFromQueue( [
146
				"$wgStyleDirectory/Vector/skin.json" => 1,
147
			] );
148
			if ( isset( $data['globals']['wgResourceModules'] ) ) {
149
				$resourceLoader->register( $data['globals']['wgResourceModules'] );
150
			}
151
152
			$moduleNames[] = 'skins.vector.styles';
153
		}
154
155
		$moduleNames[] = 'mediawiki.legacy.config';
156
157
		$rlContext = new ResourceLoaderContext( $resourceLoader, new FauxRequest( [
158
				'debug' => 'true',
159
				'lang' => $this->getLanguageCode(),
160
				'only' => 'styles',
161
		] ) );
162
163
		$styles = [];
164
		foreach ( $moduleNames as $moduleName ) {
165
			/** @var ResourceLoaderFileModule $module */
166
			$module = $resourceLoader->getModule( $moduleName );
0 ignored issues
show
Are you sure the assignment to $module is correct as $resourceLoader->getModule($moduleName) (which targets ResourceLoader::getModule()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
167
			if ( !$module ) {
168
				// T98043: Don't fatal, but it won't look as pretty.
169
				continue;
170
			}
171
172
			// Based on: ResourceLoaderFileModule::getStyles (without the DB query)
173
			$styles = array_merge( $styles, ResourceLoader::makeCombinedStyles(
174
				$module->readStyleFiles(
175
					$module->getStyleFiles( $rlContext ),
176
					$module->getFlip( $rlContext ),
177
					$rlContext
178
			) ) );
179
		}
180
181
		return implode( "\n", $styles );
182
	}
183
184
	/**
185
	 * "<link>" to index.php?css=1 for the "<head>"
186
	 *
187
	 * @return string
188
	 */
189
	private function getCssUrl() {
190
		return Html::linkedStyle( $_SERVER['PHP_SELF'] . '?css=1' );
191
	}
192
193
	public function useShortHeader( $use = true ) {
194
		$this->useShortHeader = $use;
195
	}
196
197
	public function allowFrames( $allow = true ) {
198
		$this->allowFrames = $allow;
199
	}
200
201
	public function flush() {
202
		if ( !$this->headerDone ) {
203
			$this->outputHeader();
204
		}
205
		if ( !$this->redirectTarget && strlen( $this->contents ) ) {
206
			echo $this->contents;
207
			flush();
208
			$this->contents = '';
209
		}
210
	}
211
212
	/**
213
	 * @return string
214
	 */
215
	public function getDir() {
216
		global $wgLang;
217
218
		return is_object( $wgLang ) ? $wgLang->getDir() : 'ltr';
219
	}
220
221
	/**
222
	 * @return string
223
	 */
224
	public function getLanguageCode() {
225
		global $wgLang;
226
227
		return is_object( $wgLang ) ? $wgLang->getCode() : 'en';
228
	}
229
230
	/**
231
	 * @return string[]
232
	 */
233
	public function getHeadAttribs() {
234
		return [
235
			'dir' => $this->getDir(),
236
			'lang' => wfBCP47( $this->getLanguageCode() ),
237
		];
238
	}
239
240
	/**
241
	 * Get whether the header has been output
242
	 *
243
	 * @return bool
244
	 */
245
	public function headerDone() {
246
		return $this->headerDone;
247
	}
248
249
	public function outputHeader() {
250
		$this->headerDone = true;
251
		$this->parent->request->response()->header( 'Content-Type: text/html; charset=utf-8' );
252
253
		if ( !$this->allowFrames ) {
254
			$this->parent->request->response()->header( 'X-Frame-Options: DENY' );
255
		}
256
257
		if ( $this->redirectTarget ) {
258
			$this->parent->request->response()->header( 'Location: ' . $this->redirectTarget );
259
260
			return;
261
		}
262
263
		if ( $this->useShortHeader ) {
264
			$this->outputShortHeader();
265
266
			return;
267
		}
268
?>
269
<?php echo Html::htmlHeader( $this->getHeadAttribs() ); ?>
270
271
<head>
272
	<meta name="robots" content="noindex, nofollow" />
273
	<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
274
	<title><?php $this->outputTitle(); ?></title>
275
	<?php echo $this->getCssUrl() . "\n"; ?>
276
	<?php echo $this->getJQuery() . "\n"; ?>
277
	<?php echo Html::linkedScript( 'config.js' ) . "\n"; ?>
278
</head>
279
280
<?php echo Html::openElement( 'body', [ 'class' => $this->getDir() ] ) . "\n"; ?>
281
<div id="mw-page-base"></div>
282
<div id="mw-head-base"></div>
283
<div id="content" class="mw-body">
284
<div id="bodyContent" class="mw-body-content">
285
286
<h1><?php $this->outputTitle(); ?></h1>
287
<?php
288
	}
289
290
	public function outputFooter() {
291
		if ( $this->useShortHeader ) {
292
			echo Html::closeElement( 'body' ) . Html::closeElement( 'html' );
293
294
			return;
295
		}
296
?>
297
298
</div></div>
299
300
<div id="mw-panel">
301
	<div class="portal" id="p-logo">
302
	  <a style="background-image: url(images/installer-logo.png);"
303
		href="https://www.mediawiki.org/"
304
		title="Main Page"></a>
305
	</div>
306
<?php
307
	$message = wfMessage( 'config-sidebar' )->plain();
308
	foreach ( explode( '----', $message ) as $section ) {
309
		echo '<div class="portal"><div class="body">';
310
		echo $this->parent->parse( $section, true );
311
		echo '</div></div>';
312
	}
313
?>
314
</div>
315
316
<?php
317
		echo Html::closeElement( 'body' ) . Html::closeElement( 'html' );
318
	}
319
320
	public function outputShortHeader() {
321
?>
322
<?php echo Html::htmlHeader( $this->getHeadAttribs() ); ?>
323
<head>
324
	<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
325
	<meta name="robots" content="noindex, nofollow" />
326
	<title><?php $this->outputTitle(); ?></title>
327
	<?php echo $this->getCssUrl() . "\n"; ?>
328
	<?php echo $this->getJQuery(); ?>
329
	<?php echo Html::linkedScript( 'config.js' ); ?>
330
</head>
331
332
<body style="background-image: none">
333
<?php
334
	}
335
336
	public function outputTitle() {
337
		global $wgVersion;
338
		echo wfMessage( 'config-title', $wgVersion )->escaped();
339
	}
340
341
	/**
342
	 * @return string
343
	 */
344
	public function getJQuery() {
345
		return Html::linkedScript( "../resources/lib/jquery/jquery.js" );
346
	}
347
348
}
349