2 // @codingStandardsIgnoreFile Generic.Arrays.DisallowLongArraySyntax
3 // @codingStandardsIgnoreFile Generic.Files.LineLength
4 // @codingStandardsIgnoreFile MediaWiki.Usage.DirUsage.FunctionFound
6 * Check PHP Version, as well as for composer dependencies in entry points,
7 * and display something vaguely comprehensible in the event of a totally
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 * http://www.gnu.org/copyleft/gpl.html
27 class PHPVersionCheck
{
28 /* @var string The number of the MediaWiki version used */
29 var $mwVersion = '1.29';
30 /* @var string The minimum php version for MediaWiki to run */
31 var $minimumVersionPHP = '5.5.9';
32 var $functionsExtensionsMapping = array(
33 'mb_substr' => 'mbstring',
34 'utf8_encode' => 'xml',
35 'ctype_digit' => 'ctype',
36 'json_decode' => 'json',
41 * @var string Which entry point we are protecting. One of:
45 * - mw-config/index.php
48 var $entryPoint = null;
51 * @param string $entryPoint Which entry point we are protecting. One of:
55 * - mw-config/index.php
59 function setEntryPoint( $entryPoint ) {
60 $this->entryPoint
= $entryPoint;
64 * Returns the version of the installed php implementation.
68 function getPHPImplVersion() {
73 * Displays an error, if the installed php version does not meet the minimum requirement.
77 function checkRequiredPHPVersion() {
78 if ( !function_exists( 'version_compare' )
79 ||
version_compare( $this->getPHPImplVersion(), $this->minimumVersionPHP
) < 0
81 $shortText = "MediaWiki $this->mwVersion requires at least PHP version"
82 . " $this->minimumVersionPHP, you are using PHP {$this->getPHPImplVersion()}.";
84 $longText = "Error: You might be using on older PHP version. \n"
85 . "MediaWiki $this->mwVersion needs PHP $this->minimumVersionPHP or higher.\n\n"
86 . "Check if you have a newer php executable with a different name, "
87 . "such as php5.\n\n";
90 Please consider <a href="http://www.php.net/downloads.php">upgrading your copy of PHP</a>.
91 PHP versions less than 5.5.0 are no longer supported by the PHP Group and will not receive
92 security or bugfix updates.
95 If for some reason you are unable to upgrade your PHP version, you will need to
96 <a href="https://www.mediawiki.org/wiki/Download">download</a> an older version
97 of MediaWiki from our website. See our
98 <a href="https://www.mediawiki.org/wiki/Compatibility#PHP">compatibility page</a>
99 for details of which versions are compatible with prior versions of PHP.
101 $this->triggerError( 'Supported PHP versions', $shortText, $longText, $longHtml );
106 * Displays an error, if the vendor/autoload.php file could not be found.
110 function checkVendorExistence() {
111 if ( !file_exists( dirname( __FILE__
) . '/../vendor/autoload.php' ) ) {
112 $shortText = "Installing some external dependencies (e.g. via composer) is required.";
114 $longText = "Error: You are missing some external dependencies. \n"
115 . "MediaWiki now also has some external dependencies that need to be installed\n"
116 . "via composer or from a separate git repo. Please see\n"
117 . "https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries\n"
118 . "for help on installing the required components.";
121 MediaWiki now also has some external dependencies that need to be installed via
122 composer or from a separate git repo. Please see
123 <a href="https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries">mediawiki.org</a>
124 for help on installing the required components.
127 $this->triggerError( 'External dependencies', $shortText, $longText, $longHtml );
132 * Displays an error, if a PHP extension does not exist.
136 function checkExtensionExistence() {
137 $missingExtensions = array();
138 foreach ( $this->functionsExtensionsMapping
as $function => $extension ) {
139 if ( !function_exists( $function ) ) {
140 $missingExtensions[] = $extension;
144 if ( $missingExtensions ) {
145 $shortText = "Installing some PHP extensions is required.";
147 $missingExtText = '';
148 $missingExtHtml = '';
149 $baseUrl = 'https://secure.php.net';
150 foreach ( $missingExtensions as $ext ) {
151 $missingExtText .= " * $ext <$baseUrl/$ext>\n";
152 $missingExtHtml .= "<li><b>$ext</b> "
153 . "(<a href=\"$baseUrl/$ext\">more information</a>)</li>";
156 $cliText = "Error: Missing one or more required components of PHP.\n"
157 . "You are missing a required extension to PHP that MediaWiki needs.\n"
158 . "Please install:\n" . $missingExtText;
161 You are missing a required extension to PHP that MediaWiki
162 requires to run. Please install:
168 $this->triggerError( 'Required components', $shortText, $cliText, $longHtml );
173 * Output headers that prevents error pages to be cached.
175 function outputHTMLHeader() {
176 $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ?
$_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
178 header( "$protocol 500 MediaWiki configuration Error" );
179 // Don't cache error pages! They cause no end of trouble...
180 header( 'Cache-control: none' );
181 header( 'Pragma: no-cache' );
185 * Returns an error page, which is suitable for output to the end user via a web browser.
192 function getIndexErrorOutput( $title, $longHtml, $shortText ) {
193 $pathinfo = pathinfo( $_SERVER['SCRIPT_NAME'] );
194 if ( $this->entryPoint
== 'mw-config/index.php' ) {
195 $dirname = dirname( $pathinfo['dirname'] );
197 $dirname = $pathinfo['dirname'];
200 htmlspecialchars( str_replace( '//', '/', $dirname . '/' ) .
201 'resources/assets/mediawiki.png' );
202 $shortHtml = htmlspecialchars( $shortText );
204 header( 'Content-type: text/html; charset=UTF-8' );
206 $finalOutput = <<<HTML
208 <html lang="en" dir="ltr">
210 <meta charset="UTF-8" />
211 <title>MediaWiki {$this->mwVersion}</title>
212 <style media='screen'>
215 background-color: #fff;
216 font-family: sans-serif;
233 <img src="{$encLogo}" alt='The MediaWiki logo' />
234 <h1>MediaWiki {$this->mwVersion} internal error</h1>
252 * Display something vaguely comprehensible in the event of a totally unrecoverable error.
253 * Does not assume access to *anything*; no globals, no autoloader, no database, no localisation.
254 * Safe for PHP4 (and putting this here means that WebStart.php and GlobalSettings.php
255 * no longer need to be).
257 * Calling this function kills execution immediately.
259 * @param string $title HTML code to be put within an <h2> tag
260 * @param string $shortText
261 * @param string $longText
262 * @param string $longHtml
264 function triggerError( $title, $shortText, $longText, $longHtml ) {
265 switch ( $this->entryPoint
) {
267 $finalOutput = $longText;
270 case 'mw-config/index.php':
271 $this->outputHTMLHeader();
272 $finalOutput = $this->getIndexErrorOutput( $title, $longHtml, $shortText );
275 $this->outputHTMLHeader();
276 $finalOutput = "/* $shortText */";
279 $this->outputHTMLHeader();
280 // Handle everything that's not index.php
281 $finalOutput = $shortText;
284 echo "$finalOutput\n";
290 * Check php version and that external dependencies are installed, and
291 * display an informative error if either condition is not satisfied.
293 * @note Since we can't rely on anything, the minimum PHP versions and MW current
294 * version are hardcoded here
296 function wfEntryPointCheck( $entryPoint ) {
297 $phpVersionCheck = new PHPVersionCheck();
298 $phpVersionCheck->setEntryPoint( $entryPoint );
299 $phpVersionCheck->checkRequiredPHPVersion();
300 $phpVersionCheck->checkVendorExistence();
301 $phpVersionCheck->checkExtensionExistence();