MediaWiki fundraising/REL1_35
PHPVersionCheck.php
Go to the documentation of this file.
1<?php
21// phpcs:disable Generic.Arrays.DisallowLongArraySyntax,PSR2.Classes.PropertyDeclaration,MediaWiki.Usage.DirUsage
22// phpcs:disable Squiz.Scope.MemberVarScope.Missing,Squiz.Scope.MethodScope.Missing
36 var $mwVersion = '1.35';
37
38 /* @var array A mapping of PHP functions to PHP extensions. */
40 'mb_substr' => 'mbstring',
41 'xml_parser_create' => 'xml',
42 'ctype_digit' => 'ctype',
43 'json_decode' => 'json',
44 'iconv' => 'iconv',
45 'mime_content_type' => 'fileinfo',
46 );
47
51 var $format = 'text';
52
56 var $scriptPath = '/';
57
63 function setFormat( $format ) {
64 $this->format = $format;
65 }
66
73 $this->scriptPath = $scriptPath;
74 }
75
80 $minimumVersion = '7.3.19';
81
95 $knownBad = array(
96 // https://bugs.php.net/bug.php?id=79174 as a regression from https://bugs.php.net/bug.php?id=78929
97 'T243667, T291127' => '7.4.0 - 7.4.2'
98 );
99
100 $passes = version_compare( PHP_VERSION, $minimumVersion, '>=' );
101
102 $versionString = "PHP $minimumVersion or higher";
103
104 // Left as a programmatic check to make it easier to update.
105 if ( count( $knownBad ) ) {
106 $versionString .= ' (and not ' . implode( ', ', array_values( $knownBad ) ) . ')';
107
108 foreach ( $knownBad as $task => $range ) {
109 // As we don't have composer at this point, we have to do our own version range checking.
110 if ( strpos( $range, '-' ) ) {
111 $passes = $passes && !(
112 version_compare( PHP_VERSION, trim( strstr( $range, '-', true ) ), '>=' )
113 && version_compare( PHP_VERSION, trim( substr( strstr( $range, '-', false ), 1 ) ), '<' )
114 );
115 } else {
116 $passes = $passes && version_compare( PHP_VERSION, trim( $range ), '<>' );
117 }
118 }
119 }
120
121 if ( !$passes ) {
122 $cliText = "Error: You are using an unsupported PHP version (PHP " . PHP_VERSION . ").\n"
123 . "MediaWiki $this->mwVersion needs $versionString.\n\nCheck if you might have a newer "
124 . "PHP executable with a different name.\n\n";
125
126 $web = array();
127 $web['intro'] = "MediaWiki $this->mwVersion requires $versionString; you are using PHP "
128 . PHP_VERSION . ".";
129
130 $web['longTitle'] = "Supported PHP versions";
131 // phpcs:disable Generic.Files.LineLength
132 $web['longHtml'] = <<<HTML
133 <p>
134 Please consider <a href="https://www.php.net/downloads.php">upgrading your copy of PHP</a>.
135 PHP versions less than v7.3.0 are no longer supported by the PHP Group and will not receive
136 security or bugfix updates.
137 </p>
138 <p>
139 If for some reason you are unable to upgrade your PHP version, you will need to
140 <a href="https://www.mediawiki.org/wiki/Download">download</a> an older version of
141 MediaWiki from our website. See our
142 <a href="https://www.mediawiki.org/wiki/Compatibility#PHP">compatibility page</a>
143 for details of which versions are compatible with prior versions of PHP.
144 </p>
145HTML;
146 // phpcs:enable Generic.Files.LineLength
147 $this->triggerError(
148 $web,
149 $cliText
150 );
151 }
152 }
153
158 if ( !file_exists( dirname( __FILE__ ) . '/../vendor/autoload.php' ) ) {
159 $cliText = "Error: You are missing some external dependencies. \n"
160 . "MediaWiki also has some external dependencies that need to be installed\n"
161 . "via composer or from a separate git repo. Please see\n"
162 . "https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries\n"
163 . "for help on installing the required components.";
164
165 $web = array();
166 $web['intro'] = "Installing some external dependencies (e.g. via composer) is required.";
167 $web['longTitle'] = 'External dependencies';
168 // phpcs:disable Generic.Files.LineLength
169 $web['longHtml'] = <<<HTML
170 <p>
171 MediaWiki also has some external dependencies that need to be installed via
172 composer or from a separate git repo. Please see the
173 <a href="https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries">instructions
174 for installing libraries</a> on mediawiki.org for help on installing the required components.
175 </p>
176HTML;
177 // phpcs:enable Generic.Files.LineLength
178
179 $this->triggerError( $web, $cliText );
180 }
181 }
182
187 $missingExtensions = array();
188 foreach ( $this->functionsExtensionsMapping as $function => $extension ) {
189 if ( !function_exists( $function ) ) {
190 $missingExtensions[] = $extension;
191 }
192 }
193
194 if ( $missingExtensions ) {
195 $missingExtText = '';
196 $missingExtHtml = '';
197 $baseUrl = 'https://www.php.net';
198 foreach ( $missingExtensions as $ext ) {
199 $missingExtText .= " * $ext <$baseUrl/$ext>\n";
200 $missingExtHtml .= "<li><b>$ext</b> "
201 . "(<a href=\"$baseUrl/$ext\">more information</a>)</li>";
202 }
203
204 $cliText = "Error: Missing one or more required components of PHP.\n"
205 . "You are missing a required extension to PHP that MediaWiki needs.\n"
206 . "Please install:\n" . $missingExtText;
207
208 $web = array();
209 $web['intro'] = "Installing some PHP extensions is required.";
210 $web['longTitle'] = 'Required components';
211 $web['longHtml'] = <<<HTML
212 <p>
213 You are missing a required extension to PHP that MediaWiki
214 requires to run. Please install:
215 </p>
216 <ul>
217 $missingExtHtml
218 </ul>
219HTML;
220
221 $this->triggerError( $web, $cliText );
222 }
223 }
224
228 function outputHTMLHeader() {
229 $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
230
231 header( "$protocol 500 MediaWiki configuration Error" );
232 // Don't cache error pages! They cause no end of trouble...
233 header( 'Cache-control: none' );
234 header( 'Pragma: no-cache' );
235 }
236
245 function getIndexErrorOutput( $introText, $longTitle, $longHtml ) {
246 $encLogo =
247 htmlspecialchars( str_replace( '//', '/', $this->scriptPath . '/' ) .
248 'resources/assets/mediawiki.png' );
249
250 $introHtml = htmlspecialchars( $introText );
251 $longTitleHtml = htmlspecialchars( $longTitle );
252
253 header( 'Content-type: text/html; charset=UTF-8' );
254
255 $finalOutput = <<<HTML
256<!DOCTYPE html>
257<html lang="en" dir="ltr">
258 <head>
259 <meta charset="UTF-8" />
260 <title>MediaWiki {$this->mwVersion}</title>
261 <style media="screen">
262 body {
263 color: #000;
264 background-color: #fff;
265 font-family: sans-serif;
266 padding: 2em;
267 text-align: center;
268 }
269 p, img, h1, h2, ul {
270 text-align: left;
271 margin: 0.5em 0 1em;
272 }
273 h1 {
274 font-size: 120%;
275 }
276 h2 {
277 font-size: 110%;
278 }
279 </style>
280 </head>
281 <body>
282 <img src="{$encLogo}" alt="The MediaWiki logo" />
283 <h1>MediaWiki {$this->mwVersion} internal error</h1>
284 <p>
285 {$introHtml}
286 </p>
287 <h2>{$longTitleHtml}</h2>
288 {$longHtml}
289 </body>
290</html>
291HTML;
292
293 return $finalOutput;
294 }
295
310 function triggerError( $web, $cliText ) {
311 if ( $this->format === 'html' ) {
312 // Used by index.php and mw-config/index.php
313 $this->outputHTMLHeader();
314 $finalOutput = $this->getIndexErrorOutput(
315 $web['intro'],
316 $web['longTitle'],
317 $web['longHtml']
318 );
319 } else {
320 // Used by Maintenance.php (CLI)
321 $finalOutput = $cliText;
322 }
323
324 echo "$finalOutput\n";
325 die( 1 );
326 }
327}
328
336function wfEntryPointCheck( $format = 'text', $scriptPath = '/' ) {
337 $phpVersionCheck = new PHPVersionCheck();
338 $phpVersionCheck->setFormat( $format );
339 $phpVersionCheck->setScriptPath( $scriptPath );
340 $phpVersionCheck->checkRequiredPHPVersion();
341 $phpVersionCheck->checkVendorExistence();
342 $phpVersionCheck->checkExtensionExistence();
343}
wfEntryPointCheck( $format='text', $scriptPath='/')
Check PHP version and that external dependencies are installed, and display an informative error if e...
Check PHP Version, as well as for composer dependencies in entry points, and display something vaguel...
setFormat( $format)
Set the format used for errors.
string $mwVersion
The number of the MediaWiki version used.
outputHTMLHeader()
Output headers that prevents error pages to be cached.
setScriptPath( $scriptPath)
Set the script path used for images in HTML-formatted errors.
triggerError( $web, $cliText)
Display something vaguely comprehensible in the event of a totally unrecoverable error.
getIndexErrorOutput( $introText, $longTitle, $longHtml)
Returns an error page, which is suitable for output to the end user via a web browser.
checkExtensionExistence()
Displays an error, if a PHP extension does not exist.
checkRequiredPHPVersion()
Displays an error, if the installed PHP version does not meet the minimum requirement.
checkVendorExistence()
Displays an error, if the vendor/autoload.php file could not be found.
string $format
The format used for errors.
A helper class for throttling authentication attempts.
if(!is_readable( $file)) $ext
Definition router.php:48