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() {
79 !function_exists( 'version_compare' )
80 ||
version_compare( $this->getPHPImplVersion(), $this->minimumVersionPHP
) < 0
82 $shortText = "MediaWiki $this->mwVersion requires at least PHP version"
83 . " $this->minimumVersionPHP, you are using PHP {$this->getPHPImplVersion()}.";
85 $longText = "Error: You might be using on older PHP version. \n"
86 . "MediaWiki $this->mwVersion needs PHP $this->minimumVersionPHP or higher.\n\n"
87 . "Check if you have a newer php executable with a different name, "
88 . "such as php5.\n\n";
91 Please consider <a href="http://www.php.net/downloads.php">upgrading your copy of PHP</a>.
92 PHP versions less than 5.5.0 are no longer supported by the PHP Group and will not receive
93 security or bugfix updates.
96 If for some reason you are unable to upgrade your PHP version, you will need to
97 <a href="https://www.mediawiki.org/wiki/Download">download</a> an older version
98 of MediaWiki from our website. See our
99 <a href="https://www.mediawiki.org/wiki/Compatibility#PHP">compatibility page</a>
100 for details of which versions are compatible with prior versions of PHP.
102 $this->triggerError( 'Supported PHP versions', $shortText, $longText, $longHtml );
107 * Displays an error, if the vendor/autoload.php file could not be found.
111 function checkVendorExistence() {
112 if ( !file_exists( dirname( __FILE__
) . '/../vendor/autoload.php' ) ) {
113 $shortText = "Installing some external dependencies (e.g. via composer) is required.";
115 $longText = "Error: You are missing some external dependencies. \n"
116 . "MediaWiki now also has some external dependencies that need to be installed\n"
117 . "via composer or from a separate git repo. Please see\n"
118 . "https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries\n"
119 . "for help on installing the required components.";
122 MediaWiki now also has some external dependencies that need to be installed via
123 composer or from a separate git repo. Please see
124 <a href="https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries">mediawiki.org</a>
125 for help on installing the required components.
128 $this->triggerError( 'External dependencies', $shortText, $longText, $longHtml );
133 * Displays an error, if a PHP extension does not exist.
137 function checkExtensionExistence() {
138 $missingExtensions = array();
139 foreach ( $this->functionsExtensionsMapping
as $function => $extension ) {
140 if ( !function_exists( $function ) ) {
141 $missingExtensions[] = $extension;
145 if ( $missingExtensions ) {
146 $shortText = "Installing some PHP extensions is required.";
148 $missingExtText = '';
149 $missingExtHtml = '';
150 $baseUrl = 'https://secure.php.net';
151 foreach ( $missingExtensions as $ext ) {
152 $missingExtText .= " * $ext <$baseUrl/$ext>\n";
153 $missingExtHtml .= "<li><b>$ext</b> "
154 . "(<a href=\"$baseUrl/$ext\">more information</a>)</li>";
157 $cliText = "Error: Missing one or more required components of PHP.\n"
158 . "You are missing a required extension to PHP that MediaWiki needs.\n"
159 . "Please install:\n" . $missingExtText;
162 You are missing a required extension to PHP that MediaWiki
163 requires to run. Please install:
169 $this->triggerError( 'Required components', $shortText, $cliText, $longHtml );
174 * Output headers that prevents error pages to be cached.
176 function outputHTMLHeader() {
177 $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ?
$_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
179 header( "$protocol 500 MediaWiki configuration Error" );
180 // Don't cache error pages! They cause no end of trouble...
181 header( 'Cache-control: none' );
182 header( 'Pragma: no-cache' );
186 * Returns an error page, which is suitable for output to the end user via a web browser.
193 function getIndexErrorOutput( $title, $longHtml, $shortText ) {
194 $pathinfo = pathinfo( $_SERVER['SCRIPT_NAME'] );
195 if ( $this->entryPoint
== 'mw-config/index.php' ) {
196 $dirname = dirname( $pathinfo['dirname'] );
198 $dirname = $pathinfo['dirname'];
201 htmlspecialchars( str_replace( '//', '/', $dirname . '/' ) .
202 'resources/assets/mediawiki.png' );
203 $shortHtml = htmlspecialchars( $shortText );
205 header( 'Content-type: text/html; charset=UTF-8' );
207 $finalOutput = <<<HTML
209 <html lang="en" dir="ltr">
211 <meta charset="UTF-8" />
212 <title>MediaWiki {$this->mwVersion}</title>
213 <style media='screen'>
216 background-color: #fff;
217 font-family: sans-serif;
234 <img src="{$encLogo}" alt='The MediaWiki logo' />
235 <h1>MediaWiki {$this->mwVersion} internal error</h1>
253 * Display something vaguely comprehensible in the event of a totally unrecoverable error.
254 * Does not assume access to *anything*; no globals, no autoloader, no database, no localisation.
255 * Safe for PHP4 (and putting this here means that WebStart.php and GlobalSettings.php
256 * no longer need to be).
258 * Calling this function kills execution immediately.
260 * @param string $title HTML code to be put within an <h2> tag
261 * @param string $shortText
262 * @param string $longText
263 * @param string $longHtml
265 function triggerError( $title, $shortText, $longText, $longHtml ) {
266 switch ( $this->entryPoint
) {
268 $finalOutput = $longText;
271 case 'mw-config/index.php':
272 $this->outputHTMLHeader();
273 $finalOutput = $this->getIndexErrorOutput( $title, $longHtml, $shortText );
276 $this->outputHTMLHeader();
277 $finalOutput = "/* $shortText */";
280 $this->outputHTMLHeader();
281 // Handle everything that's not index.php
282 $finalOutput = $shortText;
285 echo "$finalOutput\n";
291 * Check php version and that external dependencies are installed, and
292 * display an informative error if either condition is not satisfied.
294 * @note Since we can't rely on anything, the minimum PHP versions and MW current
295 * version are hardcoded here
297 function wfEntryPointCheck( $entryPoint ) {
298 $phpVersionCheck = new PHPVersionCheck();
299 $phpVersionCheck->setEntryPoint( $entryPoint );
300 $phpVersionCheck->checkRequiredPHPVersion();
301 $phpVersionCheck->checkVendorExistence();
302 $phpVersionCheck->checkExtensionExistence();