Add connection charset sync with WP and convert existing data to it

This commit is contained in:
Tautvidas Sipavičius
2017-05-18 00:00:00 +03:00
parent 21d0c3518e
commit a6eb1b06da
5 changed files with 68 additions and 6 deletions

View File

@ -32,6 +32,7 @@ class Database {
$driver_options = array( $driver_options = array(
'TIME_ZONE = "' . Env::$db_timezone_offset . '"', 'TIME_ZONE = "' . Env::$db_timezone_offset . '"',
'sql_mode=(SELECT REPLACE(@@sql_mode,"ONLY_FULL_GROUP_BY",""))', 'sql_mode=(SELECT REPLACE(@@sql_mode,"ONLY_FULL_GROUP_BY",""))',
'NAMES ' . Env::$db_charset . ' COLLATE ' . ENV::$db_collation,
); );
$current_options = ORM::for_table("") $current_options = ORM::for_table("")
->raw_query('SELECT @@session.wait_timeout as wait_timeout') ->raw_query('SELECT @@session.wait_timeout as wait_timeout')

View File

@ -28,6 +28,8 @@ class Env {
static $db_username; static $db_username;
static $db_password; static $db_password;
static $db_charset; static $db_charset;
static $db_collation;
static $db_charset_collate;
static $db_timezone_offset; static $db_timezone_offset;
static $required_permission = 'manage_options'; static $required_permission = 'manage_options';
@ -62,7 +64,9 @@ class Env {
self::$db_name = DB_NAME; self::$db_name = DB_NAME;
self::$db_username = DB_USER; self::$db_username = DB_USER;
self::$db_password = DB_PASSWORD; self::$db_password = DB_PASSWORD;
self::$db_charset = $wpdb->get_charset_collate(); self::$db_charset = $wpdb->charset;
self::$db_collation = $wpdb->collate;
self::$db_charset_collate = $wpdb->get_charset_collate();
self::$db_source_name = self::dbSourceName(self::$db_host, self::$db_socket, self::$db_port); self::$db_source_name = self::dbSourceName(self::$db_host, self::$db_socket, self::$db_port);
self::$db_timezone_offset = self::getDbTimezoneOffset(); self::$db_timezone_offset = self::getDbTimezoneOffset();
} }

View File

@ -438,6 +438,7 @@ class Menu {
wp_enqueue_media(); wp_enqueue_media();
wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js')); wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js'));
wp_enqueue_style('editor', includes_url('css/editor.css')); wp_enqueue_style('editor', includes_url('css/editor.css'));
$this->displayPage('newsletter/editor.html', $data); $this->displayPage('newsletter/editor.html', $data);
} }

View File

@ -12,7 +12,7 @@ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
class Migrator { class Migrator {
function __construct() { function __construct() {
$this->prefix = Env::$db_prefix; $this->prefix = Env::$db_prefix;
$this->charset = Env::$db_charset; $this->charset_collate = Env::$db_charset_collate;
$this->models = array( $this->models = array(
'segments', 'segments',
'settings', 'settings',
@ -369,7 +369,7 @@ class Migrator {
$sql = array(); $sql = array();
$sql[] = "CREATE TABLE " . $table . " ("; $sql[] = "CREATE TABLE " . $table . " (";
$sql = array_merge($sql, $attributes); $sql = array_merge($sql, $attributes);
$sql[] = ") " . $this->charset . ";"; $sql[] = ") " . $this->charset_collate . ";";
return implode("\n", $sql); return implode("\n", $sql);
} }

View File

@ -42,7 +42,7 @@ class Populator {
} }
function up() { function up() {
global $wpdb; $this->convertExistingDataToUTF8();
array_map(array($this, 'populate'), $this->models); array_map(array($this, 'populate'), $this->models);
@ -308,4 +308,60 @@ class Populator {
) )
); );
} }
/*
* MailPoet versions 3.0.0-beta.31 and older used the default MySQL connection
* character set, which usually defaults to latin1, but stored UTF-8 data.
* This method converts existing incorrectly stored data that uses the
* default character set, into a new character set that is used by WordPress.
*/
public function convertExistingDataToUTF8() {
global $wpdb;
if(!version_compare(get_option('mailpoet_db_version'), '3.0.0-beta.31', '<=')) {
// Data conversion should only be performed only once, when migrating from
// older version
return;
}
$source_charset = $wpdb->get_var('SELECT @@GLOBAL.character_set_connection');
$destination_charset = $wpdb->get_var('SELECT @@SESSION.character_set_connection');
if($source_charset === $destination_charset) return;
$tables = array(
'segments' => array('name', 'type', 'description'),
'settings' => array('name', 'value'),
'custom_fields' => array('name', 'type', 'params'),
'sending_queues' => array('type', 'newsletter_rendered_body', 'newsletter_rendered_subject', 'subscribers', 'status'),
'subscribers' => array('first_name', 'last_name', 'email', 'status', 'subscribed_ip', 'confirmed_ip', 'unconfirmed_data'),
'subscriber_segment' => array('status'),
'subscriber_custom_field' => array('value'),
'newsletters' => array('hash', 'subject', 'type', 'sender_address', 'sender_name', 'status', 'reply_to_address', 'reply_to_name', 'preheader', 'body'),
'newsletter_templates' => array('name', 'description', 'body', 'thumbnail'),
'newsletter_option_fields' => array('name', 'newsletter_type'),
'newsletter_option' => array('value'),
'newsletter_links' => array('url', 'hash'),
'forms' => array('name', 'body', 'settings', 'styles'),
);
foreach($tables as $table => $columns) {
$query = "UPDATE `%s` SET %s";
$columns_query = array();
foreach($columns as $column) {
$columns_query[] = sprintf(
'`%1$s` = convert(cast(convert(`%1$s` using `%2$s`) as binary) using %3$s)',
$column,
$source_charset,
$destination_charset
);
}
$wpdb->query(sprintf(
$query,
$this->prefix . $table,
implode(', ', $columns_query)
));
}
}
} }