Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add install and runtime status warnings if MySQL utf8mb4 is not supported #13425

Merged
merged 5 commits into from
Feb 16, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions CRM/Utils/Check/Component/Env.php
Original file line number Diff line number Diff line change
Expand Up @@ -927,4 +927,61 @@ public function checkResourceUrl() {
return $messages;
}

/**
* Check for utf8mb4 support by MySQL.
*
* @return array<CRM_Utils_Check_Message> an empty array, or a list of warnings
*/
public function checkMysqlUtf8mb4() {
$messages = array();

if (CRM_Core_DAO::getConnection()->phptype != 'mysqli') {
return $messages;
}

try {
// Create a temporary table to avoid implicit commit.
CRM_Core_DAO::executeQuery('CREATE TEMPORARY TABLE civicrm_utf8mb4_test (id VARCHAR(255), PRIMARY KEY(id(255))) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC ENGINE=INNODB');
CRM_Core_DAO::executeQuery('DROP TEMPORARY TABLE civicrm_utf8mb4_test');
}
catch (PEAR_Exception $e) {
$messages[] = new CRM_Utils_Check_Message(
__FUNCTION__,
ts('Future versions of CiviCRM may require MySQL utf8mb4 support. 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'),
ts('MySQL utf8mb4 Support'),
\Psr\Log\LogLevel::WARNING,
'fa-database'
);
}
// Ensure that the MySQL driver supports utf8mb4 encoding.
$version = mysqli_get_client_info(CRM_Core_DAO::getConnection()->connection);
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', '<')) {
$messages[] = new CRM_Utils_Check_Message(
__FUNCTION__,
ts('It is recommended, though not yet required, to upgrade your PHP MySQL driver (mysqlnd) to >= 5.0.9 for utf8mb4 support.'),
ts('PHP MySQL Driver (mysqlnd)'),
\Psr\Log\LogLevel::WARNING,
'fa-server'
);
}
}
else {
// The libmysqlclient driver supports utf8mb4 starting at version 5.5.3.
if (version_compare($version, '5.5.3', '<')) {
$messages[] = new CRM_Utils_Check_Message(
__FUNCTION__,
ts('It is recommended, though not yet required, to upgrade your PHP MySQL driver (libmysqlclient) to >= 5.0.9 for utf8mb4 support.'),
mfb marked this conversation as resolved.
Show resolved Hide resolved
ts('PHP MySQL Driver (libmysqlclient)'),
\Psr\Log\LogLevel::WARNING,
'fa-server'
);
}
}

return $messages;
}
mfb marked this conversation as resolved.
Show resolved Hide resolved

}
62 changes: 62 additions & 0 deletions Civi/Install/Requirements.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Requirements {
'checkMysqlTrigger',
'checkMysqlThreadStack',
'checkMysqlLockTables',
'checkMysqlUtf8mb4',
);

/**
Expand Down Expand Up @@ -582,4 +583,65 @@ public function checkFilepathIsWritable($file_paths) {
return $results;
}

/**
* @param $db_config
*
* @return array
*/
public function checkMysqlUtf8mb4($db_config) {
$results = array(
'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;
}

$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';
mfb marked this conversation as resolved.
Show resolved Hide resolved
mysqli_close($conn);
return $results;
}
mysqli_query('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.';
mfb marked this conversation as resolved.
Show resolved Hide resolved
mysqli_close($conn);
return $results;
}
}

mysqli_close($conn);
return $results;
}

}
61 changes: 61 additions & 0 deletions install/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,16 @@ public function checkdatabase($databaseConfig, $dbName) {
ts('Unable to create triggers. This MySQL user is missing the CREATE TRIGGERS privilege.'),
)
);
$this->requireMySQLUtf8mb4($databaseConfig['server'],
$databaseConfig['username'],
$databaseConfig['password'],
$databaseConfig['database'],
array(
ts("MySQL %1 Configuration", array(1 => $dbName)),
ts('Is the <code>utf8mb4</code> character set supported?'),
ts('This MySQL server does not support the <code>utf8mb4</code> character set.'),
)
);
}
}
}
Expand Down Expand Up @@ -1333,6 +1343,57 @@ public function requireServerVariables($varNames, $errorMessage) {
}
}

/**
* @param $server
* @param string $username
* @param $password
* @param $database
* @param $testDetails
*/
public function requireMysqlUtf8mb4($server, $username, $password, $database, $testDetails) {
$this->testing($testDetails);
$conn = $this->connect($server, $username, $password);
if (!$conn) {
$testDetails[2] = ts('Could not connect to the database server.');
$this->error($testDetails);
return;
}

if (!@mysqli_select_db($conn, $database)) {
$testDetails[2] = ts('Could not select the database.');
$this->error($testDetails);
return;
}

$result = 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 (!$result) {
$testDetails[2] = ts('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');
$this->warning($testDetails);
return;
}
$result = 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', '<')) {
$testDetails[2] = 'It is recommended, though not yet required, to upgrade your PHP MySQL driver (mysqlnd) to >= 5.0.9 for utf8mb4 support.';
$this->warning($testDetails);
return;
}
}
else {
// The libmysqlclient driver supports utf8mb4 starting at version 5.5.3.
if (version_compare($version, '5.5.3', '<')) {
$testDetails[2] = 'It is recommended, though not yet required, to upgrade your PHP MySQL driver (libmysqlclient) to >= 5.5.3 for utf8mb4 support.';
$this->warning($testDetails);
return;
}
}
}

/**
* @param $testDetails
*
Expand Down