From 851a0018ed2e11721a9d2867f85d9f80e9f33cc3 Mon Sep 17 00:00:00 2001 From: Gary Pendergast Date: Thu, 8 Sep 2016 23:53:25 +0000 Subject: [PATCH] Database: Fall back to `utf8` when `utf8mb4` isn't supported. Sometimes, `DB_CHARSET` will be set to `utf8mb4`, even if the current setup doesn't support `utf8mb4`. After [38442], this can cause significant character set failures, causing the connection to fall back to `latin1`. Instead of doing this, we now check that the connection supports `utf8mb4` before trying to use it, and fall back to `utf8` when we need to. Merge of [38580] to the 4.6 branch. Fixes #37982. git-svn-id: https://develop.svn.wordpress.org/branches/4.6@38581 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/wp-db.php | 5 +++++ tests/phpunit/tests/db.php | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/wp-includes/wp-db.php b/src/wp-includes/wp-db.php index 8ebee4c40e..8057bcc04e 100644 --- a/src/wp-includes/wp-db.php +++ b/src/wp-includes/wp-db.php @@ -779,6 +779,11 @@ class wpdb { $charset = 'utf8mb4'; } + if ( 'utf8mb4' === $charset && ! $this->has_cap( 'utf8mb4' ) ) { + $charset = 'utf8'; + $collate = str_replace( 'utf8mb4_', 'utf8_', $collate ); + } + if ( 'utf8mb4' === $charset ) { // _general_ is outdated, so we can upgrade it to _unicode_, instead. if ( ! $collate || 'utf8_general_ci' === $collate ) { diff --git a/tests/phpunit/tests/db.php b/tests/phpunit/tests/db.php index a876869346..d67926e9fc 100644 --- a/tests/phpunit/tests/db.php +++ b/tests/phpunit/tests/db.php @@ -1029,4 +1029,23 @@ class Tests_DB extends WP_UnitTestCase { $this->assertSame( 'utf8mb4_swedish_ci', $result['collate'] ); } + + /** + * @ticket 37982 + */ + function test_charset_switched_to_utf8() { + global $wpdb; + + if ( $wpdb->has_cap( 'utf8mb4' ) ) { + $this->markTestSkipped( 'This test requires utf8mb4 to not be supported.' ); + } + + $charset = 'utf8mb4'; + $collate = 'utf8mb4_general_ci'; + + $result = $wpdb->determine_charset( $charset, $collate ); + + $this->assertSame( 'utf8', $result['charset'] ); + $this->assertSame( 'utf8_general_ci', $result['collate'] ); + } }