Tuned up PdfLatex font settings
[civicrm-core.git] / Civi / Install / Requirements.php
index 13506a22b276cc2767e0e5a6c6f66d6762f45312..e7c9581106cbbe902167211a8b4d886d4c28ea43 100644 (file)
@@ -23,15 +23,18 @@ class Requirements {
    */
   const REQUIREMENT_ERROR = 2;
 
-  protected $system_checks = array(
+  /**
+   * @var array
+   */
+  protected $system_checks = [
     'checkMemory',
     'checkServerVariables',
     'checkMysqlConnectExists',
     'checkJsonEncodeExists',
     'checkMultibyteExists',
-  );
+  ];
 
-  protected $database_checks = array(
+  protected $database_checks = [
     'checkMysqlConnection',
     'checkMysqlVersion',
     'checkMysqlInnodb',
@@ -40,7 +43,8 @@ class Requirements {
     'checkMysqlTrigger',
     'checkMysqlThreadStack',
     'checkMysqlLockTables',
-  );
+    'checkMysqlUtf8mb4',
+  ];
 
   /**
    * Run all requirements tests.
@@ -69,7 +73,7 @@ class Requirements {
    * @return array
    */
   public function checkSystem(array $file_paths) {
-    $errors = array();
+    $errors = [];
 
     $errors[] = $this->checkFilepathIsWritable($file_paths);
     foreach ($this->system_checks as $check) {
@@ -93,7 +97,7 @@ class Requirements {
    * @return array
    */
   public function checkDatabase(array $db_config) {
-    $errors = array();
+    $errors = [];
 
     foreach ($this->database_checks as $check) {
       $errors[] = $this->$check($db_config);
@@ -105,7 +109,7 @@ class Requirements {
   /**
    * Generates a mysql connection
    *
-   * @param $db_confic array
+   * @param $db_config array
    * @return object mysqli connection
    */
   protected function connect($db_config) {
@@ -131,11 +135,11 @@ class Requirements {
     $mem = $this->getPHPMemory();
     $mem_string = ini_get('memory_limit');
 
-    $results = array(
+    $results = [
       'title' => 'CiviCRM memory check',
       'severity' => $this::REQUIREMENT_OK,
       'details' => "You have $mem_string allocated (minimum 32Mb, recommended 64Mb)",
-    );
+    ];
 
     if ($mem < $min && $mem > 0) {
       $results['severity'] = $this::REQUIREMENT_ERROR;
@@ -177,14 +181,14 @@ class Requirements {
    * @return array
    */
   public function checkServerVariables() {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM PHP server variables',
       'severity' => $this::REQUIREMENT_OK,
       'details' => 'The required $_SERVER variables are set',
-    );
+    ];
 
-    $required_variables = array('SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME');
-    $missing = array();
+    $required_variables = ['SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME'];
+    $missing = [];
 
     foreach ($required_variables as $required_variable) {
       if (empty($_SERVER[$required_variable])) {
@@ -204,11 +208,11 @@ class Requirements {
    * @return array
    */
   public function checkJsonEncodeExists() {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM JSON encoding support',
       'severity' => $this::REQUIREMENT_OK,
       'details' => 'Function json_encode() found',
-    );
+    ];
     if (!function_exists('json_encode')) {
       $results['severity'] = $this::REQUIREMENT_ERROR;
       $results['details'] = 'Function json_encode() does not exist';
@@ -222,11 +226,11 @@ class Requirements {
    * @return array
    */
   public function checkMultibyteExists() {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM MultiByte encoding support',
       'severity' => $this::REQUIREMENT_OK,
       'details' => 'PHP Multibyte etension found',
-    );
+    ];
     if (!function_exists('mb_substr')) {
       $results['severity'] = $this::REQUIREMENT_ERROR;
       $results['details'] = 'PHP Multibyte extension has not been installed and enabled';
@@ -239,11 +243,11 @@ class Requirements {
    * @return array
    */
   public function checkMysqlConnectExists() {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM MySQL check',
       'severity' => $this::REQUIREMENT_OK,
       'details' => 'Function mysqli_connect() found',
-    );
+    ];
     if (!function_exists('mysqli_connect')) {
       $results['severity'] = $this::REQUIREMENT_ERROR;
       $results['details'] = 'Function mysqli_connect() does not exist';
@@ -258,11 +262,11 @@ class Requirements {
    * @return array
    */
   public function checkMysqlConnection(array $db_config) {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM MySQL connection',
       'severity' => $this::REQUIREMENT_OK,
       'details' => "Connected",
-    );
+    ];
 
     $conn = $this->connect($db_config);
 
@@ -288,10 +292,10 @@ class Requirements {
    */
   public function checkMysqlVersion(array $db_config) {
     $min = '5.1';
-    $results = array(
+    $results = [
       'title' => 'CiviCRM MySQL Version',
       'severity' => $this::REQUIREMENT_OK,
-    );
+    ];
 
     $conn = $this->connect($db_config);
     if (!$conn || !($info = mysqli_get_server_info($conn))) {
@@ -316,11 +320,11 @@ class Requirements {
    * @return array
    */
   public function checkMysqlInnodb(array $db_config) {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM InnoDB support',
       'severity' => $this::REQUIREMENT_ERROR,
       'details' => 'Could not determine if MySQL has InnoDB support. Assuming none.',
-    );
+    ];
 
     $conn = $this->connect($db_config);
     if (!$conn) {
@@ -351,11 +355,11 @@ class Requirements {
    * @return array
    */
   public function checkMysqlTempTables(array $db_config) {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM MySQL Temp Tables',
       'severity' => $this::REQUIREMENT_OK,
       'details' => 'MySQL server supports temporary tables',
-    );
+    ];
 
     $conn = $this->connect($db_config);
     if (!$conn) {
@@ -387,11 +391,11 @@ class Requirements {
    * @return array
    */
   public function checkMysqlTrigger($db_config) {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM MySQL Trigger',
       'severity' => $this::REQUIREMENT_OK,
       'details' => 'Database supports MySQL triggers',
-    );
+    ];
 
     $conn = $this->connect($db_config);
     if (!$conn) {
@@ -432,11 +436,11 @@ class Requirements {
    * @return array
    */
   public function checkMySQLAutoIncrementIncrementOne(array $db_config) {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM MySQL AutoIncrementIncrement',
       'severity' => $this::REQUIREMENT_OK,
       'details' => 'MySQL server auto_increment_increment is 1',
-    );
+    ];
 
     $conn = $this->connect($db_config);
     if (!$conn) {
@@ -468,11 +472,11 @@ class Requirements {
   public function checkMysqlThreadStack($db_config) {
     $min_thread_stack = 192;
 
-    $results = array(
+    $results = [
       'title' => 'CiviCRM Mysql thread stack',
       'severity' => $this::REQUIREMENT_OK,
       'details' => 'MySQL thread_stack is OK',
-    );
+    ];
 
     $conn = $this->connect($db_config);
     if (!$conn) {
@@ -487,7 +491,8 @@ class Requirements {
       return $results;
     }
 
-    $r = mysqli_query($conn, "SHOW VARIABLES LIKE 'thread_stack'"); // bytes => kb
+    // bytes => kb
+    $r = mysqli_query($conn, "SHOW VARIABLES LIKE 'thread_stack'");
     if (!$r) {
       $results['severity'] = $this::REQUIREMENT_ERROR;
       $results['details'] = 'Could not query thread_stack value';
@@ -509,11 +514,11 @@ class Requirements {
    * @return array
    */
   public function checkMysqlLockTables($db_config) {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM MySQL Lock Tables',
       'severity' => $this::REQUIREMENT_OK,
       'details' => 'Can successfully lock and unlock tables',
-    );
+    ];
 
     $conn = $this->connect($db_config);
     if (!$conn) {
@@ -561,13 +566,13 @@ class Requirements {
    * @return array
    */
   public function checkFilepathIsWritable($file_paths) {
-    $results = array(
+    $results = [
       'title' => 'CiviCRM directories are writable',
       'severity' => $this::REQUIREMENT_OK,
       'details' => 'All required directories are writable: ' . implode(', ', $file_paths),
-    );
+    ];
 
-    $unwritable_dirs = array();
+    $unwritable_dirs = [];
     foreach ($file_paths as $path) {
       if (!is_writable($path)) {
         $unwritable_dirs[] = $path;
@@ -582,4 +587,66 @@ class Requirements {
     return $results;
   }
 
+  /**
+   * @param $db_config
+   *
+   * @return array
+   */
+  public function checkMysqlUtf8mb4($db_config) {
+    $results = [
+      'title' => 'CiviCRM MySQL utf8mb4 Support',
+      'severity' => $this::REQUIREMENT_OK,
+      'details' => 'Your system supports the MySQL utf8mb4 character set.',
+    ];
+
+    $conn = $this->connect($db_config);
+    if (!$conn) {
+      $results['severity'] = $this::REQUIREMENT_ERROR;
+      $results['details'] = 'Could not connect to database';
+      return $results;
+    }
+
+    if (!@mysqli_select_db($conn, $db_config['database'])) {
+      $results['severity'] = $this::REQUIREMENT_ERROR;
+      $results['details'] = 'Could not select the database';
+      mysqli_close($conn);
+      return $results;
+    }
+
+    mysqli_query($conn, 'DROP TABLE IF EXISTS civicrm_utf8mb4_test');
+    $r = mysqli_query($conn, 'CREATE TABLE civicrm_utf8mb4_test (id VARCHAR(255), PRIMARY KEY(id(255))) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC ENGINE=INNODB');
+    if (!$r) {
+      $results['severity'] = $this::REQUIREMENT_WARNING;
+      $results['details'] = 'It is recommended, though not yet required, to configure your MySQL server for utf8mb4 support. You will need the following MySQL server configuration: innodb_large_prefix=true innodb_file_format=barracuda innodb_file_per_table=true';
+      mysqli_close($conn);
+      return $results;
+    }
+    mysqli_query($conn, 'DROP TABLE civicrm_utf8mb4_test');
+
+    // Ensure that the MySQL driver supports utf8mb4 encoding.
+    $version = mysqli_get_client_info($conn);
+    if (strpos($version, 'mysqlnd') !== FALSE) {
+      // The mysqlnd driver supports utf8mb4 starting at version 5.0.9.
+      $version = preg_replace('/^\D+([\d.]+).*/', '$1', $version);
+      if (version_compare($version, '5.0.9', '<')) {
+        $results['severity'] = $this::REQUIREMENT_WARNING;
+        $results['details'] = 'It is recommended, though not yet required, to upgrade your PHP MySQL driver (mysqlnd) to >= 5.0.9 for utf8mb4 support.';
+        mysqli_close($conn);
+        return $results;
+      }
+    }
+    else {
+      // The libmysqlclient driver supports utf8mb4 starting at version 5.5.3.
+      if (version_compare($version, '5.5.3', '<')) {
+        $results['severity'] = $this::REQUIREMENT_WARNING;
+        $results['details'] = 'It is recommended, though not yet required, to upgrade your PHP MySQL driver (libmysqlclient) to >= 5.5.3 for utf8mb4 support.';
+        mysqli_close($conn);
+        return $results;
+      }
+    }
+
+    mysqli_close($conn);
+    return $results;
+  }
+
 }