diff --git a/administrator/components/com_admin/script.php b/administrator/components/com_admin/script.php index de095d3191f2c..44193c656848c 100644 --- a/administrator/components/com_admin/script.php +++ b/administrator/components/com_admin/script.php @@ -33,7 +33,7 @@ public function update($installer) $this->deleteUnexistingFiles(); $this->updateManifestCaches(); - $this->updateDatabase(); + $this->uninstallEosPlugin(); $this->clearRadCache(); $this->updateAssets(); $this->clearStatsCache(); @@ -97,69 +97,6 @@ protected function clearStatsCache() } } - /** - * Method to update Database - * - * @return void - */ - protected function updateDatabase() - { - $db = JFactory::getDbo(); - - if (strpos($db->name, 'mysql') !== false) - { - $this->updateDatabaseMysql(); - } - - $this->uninstallEosPlugin(); - } - - /** - * Method to update MySQL Database - * - * @return void - */ - protected function updateDatabaseMysql() - { - $db = JFactory::getDbo(); - - $db->setQuery('SHOW ENGINES'); - - try - { - $results = $db->loadObjectList(); - } - catch (Exception $e) - { - echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; - - return; - } - - foreach ($results as $result) - { - if ($result->Support != 'DEFAULT') - { - continue; - } - - $db->setQuery('ALTER TABLE #__update_sites_extensions ENGINE = ' . $result->Engine); - - try - { - $db->execute(); - } - catch (Exception $e) - { - echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; - - return; - } - - break; - } - } - /** * Uninstall the 2.5 EOS plugin * diff --git a/administrator/components/com_installer/models/database.php b/administrator/components/com_installer/models/database.php index 3acc1d445e945..b7d5b0b53fd72 100644 --- a/administrator/components/com_installer/models/database.php +++ b/administrator/components/com_installer/models/database.php @@ -287,13 +287,18 @@ public function convertTablesToUtf8mb4() foreach ($queries as $query) { - try - { - $db->setQuery($query)->execute(); - } - catch (Exception $e) + $query = trim($query); + + if ($query != '' && $query{0} != '#') { - // If the query fails we will go on. It probably means we've already done this conversion. + try + { + $db->setQuery($query)->execute(); + } + catch (RuntimeException $e) + { + JFactory::getApplication()->enqueueMessage(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $e->getCode(), $e->getMessage())); + } } } } diff --git a/libraries/joomla/database/driver/mysql.php b/libraries/joomla/database/driver/mysql.php index f65745b7ff7a7..569a0866ee1e3 100644 --- a/libraries/joomla/database/driver/mysql.php +++ b/libraries/joomla/database/driver/mysql.php @@ -510,17 +510,24 @@ private function hasProfiling() private function serverClaimsUtf8mb4Support() { $client_version = mysql_get_client_info(); - $server_support = version_compare($this->getVersion(), '5.5.3', '>='); + $server_version = $this->getVersion(); - if (strpos($client_version, 'mysqlnd') !== false && $server_support) + if (version_compare($server_version, '5.5.3', '<')) { - $client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version); - - return version_compare($client_version, '5.0.9', '>='); + return false; } else { - return $server_support; + if (strpos($client_version, 'mysqlnd') !== false) + { + $client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version); + + return version_compare($client_version, '5.0.9', '>='); + } + else + { + return version_compare($client_version, '5.5.3', '>='); + } } } diff --git a/libraries/joomla/database/driver/mysqli.php b/libraries/joomla/database/driver/mysqli.php index 23cc81c58a0d5..a0a10b4353b57 100644 --- a/libraries/joomla/database/driver/mysqli.php +++ b/libraries/joomla/database/driver/mysqli.php @@ -952,17 +952,24 @@ private function hasProfiling() private function serverClaimsUtf8mb4Support() { $client_version = mysqli_get_client_info(); - $server_support = version_compare($this->getVersion(), '5.5.3', '>='); + $server_version = $this->getVersion(); - if (strpos($client_version, 'mysqlnd') !== false && $server_support) + if (version_compare($server_version, '5.5.3', '<')) { - $client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version); - - return version_compare($client_version, '5.0.9', '>='); + return false; } else { - return $server_support; + if (strpos($client_version, 'mysqlnd') !== false) + { + $client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version); + + return version_compare($client_version, '5.0.9', '>='); + } + else + { + return version_compare($client_version, '5.5.3', '>='); + } } } diff --git a/libraries/joomla/database/driver/pdomysql.php b/libraries/joomla/database/driver/pdomysql.php index 6a2055233a808..410e4284399a5 100644 --- a/libraries/joomla/database/driver/pdomysql.php +++ b/libraries/joomla/database/driver/pdomysql.php @@ -72,24 +72,20 @@ class JDatabaseDriverPdomysql extends JDatabaseDriverPdo */ public function __construct($options) { - /** - * Pre-populate the UTF-8 Multibyte compatibility flag. Unfortunately PDO won't report the server version - * unless we're connected to it and we cannot connect to it unless we know if it supports utf8mb4 which requires - * us knowing the server version. Between this chicken and egg issue we _assume_ it's supported and we'll just - * catch any problems at connection time. - */ - $this->utf8mb4 = true; - // Get some basic values from the options. $options['driver'] = 'mysql'; - $options['charset'] = (isset($options['charset'])) ? $options['charset'] : 'utf8'; - - if ($this->utf8mb4 && ($options['charset'] == 'utf8')) + if (!isset($options['charset']) || $options['charset'] == 'utf8') { $options['charset'] = 'utf8mb4'; } - $this->charset = $options['charset']; + /** + * Pre-populate the UTF-8 Multibyte compatibility flag. Unfortunately PDO won't report the server version + * unless we're connected to it, and we cannot connect to it unless we know if it supports utf8mb4, which requires + * us knowing the server version. Because of this chicken and egg issue, we _assume_ it's supported and we'll just + * catch any problems at connection time. + */ + $this->utf8mb4 = ($options['charset'] == 'utf8mb4'); // Finalize initialisation. parent::__construct($options); @@ -112,27 +108,44 @@ public function connect() } catch (\RuntimeException $e) { - // If the connection failed but not because of the wrong character set bubble up the exception - if (!$this->utf8mb4 || ($this->options['charset'] != 'utf8mb4')) + // If the connection failed, but not because of the wrong character set, then bubble up the exception. + if (!$this->utf8mb4) { throw $e; } - /** - * If the connection failed and I was trying to use the utf8mb4 charset then it is likely that the server - * doesn't support utf8mb4 despite claiming otherwise. - * - * This happens on old MySQL server versions (less than 5.5.3) using the mysqlnd PHP driver. Since mysqlnd - * masks the server version and reports only its own we can not be sure if the server actually does support - * UTF-8 Multibyte (i.e. it's MySQL 5.5.3 or later). Since the utf8mb4 charset is undefined in this case we - * catch the error and determine that utf8mb4 is not supported! + /* + * Otherwise, try connecting again without using + * utf8mb4 and see if maybe that was the problem. If the + * connection succeeds, then we will have learned that the + * client end of the connection does not support utf8mb4. */ + $this->utf8mb4 = false; $this->options['charset'] = 'utf8'; parent::connect(); } + if ($this->utf8mb4) + { + /* + * At this point we know the client supports utf8mb4. Now + * we must check if the server supports utf8mb4 as well. + */ + + $serverVersion = $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION); + $this->utf8mb4 = version_compare($serverVersion, '5.5.3', '>='); + + if (!$this->utf8mb4) + { + // Reconnect with the utf8 character set. + parent::disconnect(); + $this->options['charset'] = 'utf8'; + parent::connect(); + } + } + $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); }