Move fatal PHP functions checks to initialization
authorChad Horohoe <chadh@wikimedia.org>
Tue, 14 Jun 2016 00:52:51 +0000 (17:52 -0700)
committerChad Horohoe <chadh@wikimedia.org>
Tue, 14 Jun 2016 19:50:39 +0000 (12:50 -0700)
The installer is far too late of a place to be checking if
a function does or doesn't exist if we require it for operation.
Functions can very easily (T137509) be called prior to ever
getting to the installer check page.

Also, an old installation could've gotten past the checks if
they ran update.php --skip-compat-checks. What a scary setting!

Instead, fail hard, fast and early along with PHP version checks.
All entry points are required to go through this.

While we're here, also remove the check for mbstring.func_overload
since we already would've failed at WebStart.php

Change-Id: Ib9727979af2a4741f3cd952d13a3bb350fad43e4

includes/PHPVersionCheck.php
includes/Setup.php
includes/installer/Installer.php
includes/installer/i18n/en.json
includes/installer/i18n/qqq.json

index ab8aada..018c6f8 100644 (file)
@@ -45,6 +45,29 @@ function wfEntryPointCheck( $entryPoint ) {
                // @codingStandardsIgnoreEnd
                wfMissingVendorError( $entryPoint, $mwVersion );
        }
+
+       // List of functions and their associated PHP extension to check for
+       // @codingStandardsIgnoreStart Generic.Arrays.DisallowLongArraySyntax
+       $extensions = array(
+               'mb_substr'   => 'mbstring',
+               'utf8_encode' => 'xml',
+               'ctype_digit' => 'ctype',
+               'json_decode' => 'json',
+               'iconv'       => 'iconv',
+       );
+       // List of extensions we're missing
+       $missingExtensions = array();
+       // @codingStandardsIgnoreEnd
+
+       foreach ( $extensions as $function => $extension ) {
+               if ( !function_exists( $function ) ) {
+                       $missingExtensions[] = $extension;
+               }
+       }
+
+       if ( $missingExtensions ) {
+               wfMissingExtensions( $entryPoint, $mwVersion, $missingExtensions );
+       }
 }
 
 /**
@@ -107,7 +130,7 @@ function wfGenericError( $type, $mwVersion, $title, $shortText, $longText, $long
                                padding: 2em;
                                text-align: center;
                        }
-                       p, img, h1, h2 {
+                       p, img, h1, h2, ul  {
                                text-align: left;
                                margin: 0.5em 0 1em;
                        }
@@ -201,3 +224,38 @@ HTML;
 
        wfGenericError( $type, $mwVersion, 'External dependencies', $shortText, $longText, $longHtml );
 }
+
+/**
+ * Display an error for a PHP extension not existing.
+ *
+ * @param string $type See wfGenericError
+ * @param string $mwVersion See wfGenericError
+ * @param array $missingExts The extensions we're missing
+ */
+function wfMissingExtensions( $type, $mwVersion, $missingExts ) {
+       $shortText = "Installing some PHP extensions is required.";
+
+       $missingExtText = '';
+       $missingExtHtml = '';
+       $baseUrl = 'https://secure.php.net';
+       foreach ( $missingExts as $ext ) {
+               $missingExtText .= " * $ext <$baseUrl/$ext>\n";
+               $missingExtHtml .= "<li><b>$ext</b> "
+                       . "(<a href=\"$baseUrl/$ext\">more information</a>)</li>";
+       }
+
+       $cliText = "Error: Missing one or more required components of PHP.\n"
+               . "You are missing a required extension to PHP that MediaWiki needs.\n"
+               . "Please install:\n" . $missingExtText;
+
+       $longHtml = <<<HTML
+               You are missing a required extension to PHP that MediaWiki
+               requires to run. Please install:
+               <ul>
+               $missingExtHtml
+               </ul>
+HTML;
+
+       wfGenericError( $type, $mwVersion, 'Required components', $shortText,
+               $cliText, $longHtml );
+}
index 878b147..5877932 100644 (file)
@@ -45,12 +45,7 @@ if ( !isset( $wgVersion ) ) {
        die( 1 );
 }
 
-if ( function_exists( 'mb_internal_encoding' ) ) {
-       mb_internal_encoding( 'UTF-8' );
-} elseif ( !defined( 'MEDIAWIKI_INSTALL' ) ) {
-       echo "Error: the mbstring PHP extension is required\n";
-       die( 1 );
-}
+mb_internal_encoding( 'UTF-8' );
 
 // Set various default paths sensibly...
 $ps_default = Profiler::instance()->scopedProfileIn( $fname . '-defaults' );
index 7c161ca..4d5aa7a 100644 (file)
@@ -121,8 +121,6 @@ abstract class Installer {
        protected $envChecks = [
                'envCheckDB',
                'envCheckBrokenXML',
-               'envCheckMbstring',
-               'envCheckXML',
                'envCheckPCRE',
                'envCheckMemory',
                'envCheckCache',
@@ -136,9 +134,6 @@ abstract class Installer {
                'envCheckUploadsDirectory',
                'envCheckLibicu',
                'envCheckSuhosinMaxValueLength',
-               'envCheckCtype',
-               'envCheckIconv',
-               'envCheckJSON',
        ];
 
        /**
@@ -791,40 +786,6 @@ abstract class Installer {
                return true;
        }
 
-       /**
-        * Environment check for mbstring.func_overload.
-        * @return bool
-        */
-       protected function envCheckMbstring() {
-               if ( wfIniGetBool( 'mbstring.func_overload' ) ) {
-                       $this->showError( 'config-mbstring' );
-
-                       return false;
-               }
-
-               if ( !function_exists( 'mb_substr' ) ) {
-                       $this->showError( 'config-mbstring-absent' );
-
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        * Environment check for the XML module.
-        * @return bool
-        */
-       protected function envCheckXML() {
-               if ( !function_exists( "utf8_encode" ) ) {
-                       $this->showError( 'config-xml-bad' );
-
-                       return false;
-               }
-
-               return true;
-       }
-
        /**
         * Environment check for the PCRE module.
         *
@@ -1177,45 +1138,6 @@ abstract class Installer {
                }
        }
 
-       /**
-        * @return bool
-        */
-       protected function envCheckCtype() {
-               if ( !function_exists( 'ctype_digit' ) ) {
-                       $this->showError( 'config-ctype' );
-
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        * @return bool
-        */
-       protected function envCheckIconv() {
-               if ( !function_exists( 'iconv' ) ) {
-                       $this->showError( 'config-iconv' );
-
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        * @return bool
-        */
-       protected function envCheckJSON() {
-               if ( !function_exists( 'json_decode' ) ) {
-                       $this->showError( 'config-json' );
-
-                       return false;
-               }
-
-               return true;
-       }
-
        /**
         * Environment prep for the server hostname.
         */
index 9077082..2b7886a 100644 (file)
        "config-no-db": "Could not find a suitable database driver! You need to install a database driver for PHP.\nThe following database {{PLURAL:$2|type is|types are}} supported: $1.\n\nIf you compiled PHP yourself, reconfigure it with a database client enabled, for example, using <code>./configure --with-mysqli</code>.\nIf you installed PHP from a Debian or Ubuntu package, then you also need to install, for example, the <code>php5-mysql</code> package.",
        "config-outdated-sqlite": "<strong>Warning:</strong> you have SQLite $1, which is lower than minimum required version $2. SQLite will be unavailable.",
        "config-no-fts3": "<strong>Warning:</strong> SQLite is compiled without the [//sqlite.org/fts3.html FTS3 module], search features will be unavailable on this backend.",
-       "config-mbstring": "<strong>Fatal: [http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload mbstring.func_overload] is active!</strong>\nThis option causes errors and may corrupt data unpredictably.\nYou cannot install or use MediaWiki unless this option is disabled.",
-       "config-xml-bad": "PHP's XML module is missing.\nMediaWiki requires functions in this module and will not work in this configuration.\nYou may need to install the php-xml RPM package.",
        "config-pcre-old": "<strong>Fatal:</strong> PCRE $1 or later is required.\nYour PHP binary is linked with PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE More information].",
        "config-pcre-no-utf8": "<strong>Fatal:</strong> PHP's PCRE module seems to be compiled without PCRE_UTF8 support.\nMediaWiki requires UTF-8 support to function correctly.",
        "config-memory-raised": "PHP's <code>memory_limit</code> is $1, raised to $2.",
        "config-memory-bad": "<strong>Warning:</strong> PHP's <code>memory_limit</code> is $1.\nThis is probably too low.\nThe installation may fail!",
-       "config-ctype": "<strong>Fatal:</strong> PHP must be compiled with support for the [http://www.php.net/manual/en/ctype.installation.php Ctype extension].",
-       "config-iconv": "<strong>Fatal:</strong> PHP must be compiled with support for the [http://www.php.net/manual/en/iconv.installation.php iconv extension].",
-       "config-json": "<strong>Fatal:</strong> PHP was compiled without JSON support.\nYou must install either the PHP JSON extension or the [http://pecl.php.net/package/jsonc PECL jsonc] extension before installing MediaWiki.\n* The PHP extension is included in Red Hat Enterprise Linux (CentOS) 5 and 6, though must be enabled in <code>/etc/php.ini</code> or <code>/etc/php.d/json.ini</code>.\n* Some Linux distributions released after May 2013 omit the PHP extension, instead packaging the PECL extension as <code>php5-json</code> or <code>php-pecl-jsonc</code>.",
-       "config-mbstring-absent": "<strong>Fatal:</strong> PHP must be compiled with support for the [http://www.php.net/manual/en/mbstring.setup.php mbstring extension].",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] is installed",
        "config-apc": "[http://www.php.net/apc APC] is installed",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] is installed",
index b2ff103..66a24c0 100644 (file)
        "config-no-db": "{{doc-important|Do not translate \"<code>./configure --with-mysqli</code>\" and \"<code>php5-mysql</code>\".}}\nParameters:\n* $1 is comma separated list of database types supported by MediaWiki.\n* $2 is the count of items in $1 - for use in plural.",
        "config-outdated-sqlite": "Used as warning. Parameters:\n* $1 - the version of SQLite that has been installed\n* $2 - minimum version",
        "config-no-fts3": "A \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.",
-       "config-mbstring": "{{Related|Config-fatal}}",
-       "config-xml-bad": "Status message in the MediaWiki installer environment checks.",
        "config-pcre-old": "Parameters:\n* $1 - minimum PCRE version number\n* $2 - the installed version of [[wikipedia:PCRE|PCRE]]\n{{Related|Config-fatal}}",
        "config-pcre-no-utf8": "PCRE is a name of a programmers' library for supporting regular expressions. It can probably be translated without change.\n{{Related|Config-fatal}}",
        "config-memory-raised": "Parameters:\n* $1 is the configured <code>memory_limit</code>.\n* $2 is the value to which <code>memory_limit</code> was raised.",
        "config-memory-bad": "Parameters:\n* $1 is the configured <code>memory_limit</code>.",
-       "config-ctype": "Message if support for [http://www.php.net/manual/en/ctype.installation.php Ctype] is missing from PHP.\n{{Related|Config-fatal}}",
-       "config-iconv": "Message if support for [http://www.php.net/manual/en/iconv.installation.php iconv] is missing from PHP.\n{{Related|Config-fatal}}",
-       "config-json": "Message if support for [[wikipedia:JSON|JSON]] is missing from PHP.\n* \"[[wikipedia:Red Hat Enterprise Linux|Red Hat Enterprise Linux]]\" (RHEL) and \"[[wikipedia:CentOS|CentOS]]\" refer to two almost-identical Linux distributions. \"5 and 6\" refers to version 5 or 6 of either distribution. Because RHEL 7 likely will not include the PHP extension, do not translate as \"5 or newer\".\n* \"The [http://www.php.net/json PHP extension]\" is the JSON extension included with PHP 5.2 and newer.\n* \"The [http://pecl.php.net/package/jsonc PECL extension]\" is based on the PHP extension, though excludes code some distributions have found unacceptable (see [[phab:T49431]]).\n{{Related|Config-fatal}}",
-       "config-mbstring-absent": "Message if support for [http://www.php.net/manual/en/mbstring.installation.php mbstring] is missing from PHP.\n{{Related|Config-fatal}}",
        "config-xcache": "Message indicates if this program is available",
        "config-apc": "Message indicates if this program is available",
        "config-wincache": "Message indicates if this program is available",