Merge pull request #941 from mailpoet/mp2tomp3migration
Mp2tomp3migration phase 2
This commit is contained in:
@@ -61,7 +61,7 @@ define('mp2migrator', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
||||
}
|
||||
jQuery('#progressbar').progressbar('option', 'value', progress);
|
||||
jQuery('#progresslabel').html(progress + '%');
|
||||
if(Number(result.current !== 0)) {
|
||||
if(Number(result.current) !== 0) {
|
||||
jQuery('#skip-import').hide();
|
||||
}
|
||||
if(MailPoet.MP2Migrator.is_logging) {
|
||||
|
@@ -3,6 +3,7 @@
|
||||
namespace MailPoet\Config;
|
||||
|
||||
use MailPoet\Util\ProgressBar;
|
||||
use MailPoet\Models\Form;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\Subscriber;
|
||||
@@ -159,6 +160,7 @@ class MP2Migrator {
|
||||
$this->importSegments();
|
||||
$this->importCustomFields();
|
||||
$this->importSubscribers();
|
||||
$this->importForms();
|
||||
|
||||
if(!$this->importStopped()) {
|
||||
Setting::setValue('mailpoet_migration_complete', true);
|
||||
@@ -199,6 +201,7 @@ class MP2Migrator {
|
||||
private function resetMigrationCounters() {
|
||||
Setting::setValue('last_imported_user_id', 0);
|
||||
Setting::setValue('last_imported_list_id', 0);
|
||||
Setting::setValue('last_imported_form_id', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,17 +265,17 @@ class MP2Migrator {
|
||||
$total_count += $users_count;
|
||||
$result .= sprintf(_n('%d subscriber', '%d subscribers', $users_count, 'mailpoet'), $users_count) . "\n";
|
||||
|
||||
// Forms
|
||||
$forms_count = \ORM::for_table(MP2_FORM_TABLE)->count();
|
||||
$total_count += $forms_count;
|
||||
$result .= sprintf(_n('%d form', '%d forms', $forms_count, 'mailpoet'), $forms_count) . "\n";
|
||||
|
||||
// TODO to reactivate during the next phases
|
||||
/*
|
||||
// Emails
|
||||
$emails_count = \ORM::for_table(MP2_EMAIL_TABLE)->count();
|
||||
$total_count += $emails_count;
|
||||
$result .= sprintf(_n('%d newsletter', '%d newsletters', $emails_count, 'mailpoet'), $emails_count) . "\n";
|
||||
|
||||
// Forms
|
||||
$forms_count = \ORM::for_table(MP2_FORM_TABLE)->count();
|
||||
$total_count += $forms_count;
|
||||
$result .= sprintf(_n('%d form', '%d forms', $forms_count, 'mailpoet'), $forms_count) . "\n";
|
||||
*/
|
||||
|
||||
$this->progressbar->setTotalCount($total_count);
|
||||
@@ -424,7 +427,7 @@ class MP2Migrator {
|
||||
'id' => $custom_field['id'],
|
||||
'name' => $custom_field['name'],
|
||||
'type' => $this->mapCustomFieldType($custom_field['type']),
|
||||
'params' => $this->mapCustomFieldParams($custom_field),
|
||||
'params' => $this->mapCustomFieldParams($custom_field['name'], unserialize($custom_field['settings'])),
|
||||
);
|
||||
$custom_field = new CustomField();
|
||||
$custom_field->createOrUpdate($data);
|
||||
@@ -443,6 +446,9 @@ class MP2Migrator {
|
||||
case 'input':
|
||||
$type = 'text';
|
||||
break;
|
||||
case 'list':
|
||||
$type = 'segment';
|
||||
break;
|
||||
default:
|
||||
$type = $mp2_type;
|
||||
}
|
||||
@@ -452,17 +458,42 @@ class MP2Migrator {
|
||||
/**
|
||||
* Map the MailPoet 2 custom field settings with the MailPoet custom field params
|
||||
*
|
||||
* @param array $custom_field MP2 custom field
|
||||
* @param string $name Parameter name
|
||||
* @param array $params MP2 parameters
|
||||
* @return string serialized MP3 custom field params
|
||||
*/
|
||||
private function mapCustomFieldParams($custom_field) {
|
||||
$params = unserialize($custom_field['settings']);
|
||||
$params['label'] = $custom_field['name'];
|
||||
private function mapCustomFieldParams($name, $params) {
|
||||
if(!isset($params['label'])) {
|
||||
$params['label'] = $name;
|
||||
}
|
||||
if(isset($params['required'])) {
|
||||
$params['required'] = (bool)$params['required'];
|
||||
}
|
||||
if(isset($params['validate'])) {
|
||||
$params['validate'] = $this->mapCustomFieldValidateValue($params['validate']);
|
||||
}
|
||||
if(isset($params['date_order'])) { // Convert the date_order field
|
||||
$params['date_format'] = strtoupper($params['date_order']);
|
||||
switch($params['date_type']) {
|
||||
|
||||
case 'year_month':
|
||||
if(preg_match('/y$/i', $params['date_order'])) {
|
||||
$params['date_format'] = 'MM/YYYY';
|
||||
} else {
|
||||
$params['date_format'] = 'YYYY/MM';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'month';
|
||||
$params['date_format'] = 'MM';
|
||||
break;
|
||||
|
||||
case 'year';
|
||||
$params['date_format'] = 'YYYY';
|
||||
break;
|
||||
|
||||
default:
|
||||
$params['date_format'] = strtoupper($params['date_order']);
|
||||
}
|
||||
unset($params['date_order']);
|
||||
}
|
||||
return $params;
|
||||
@@ -739,4 +770,195 @@ class MP2Migrator {
|
||||
return $mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import the forms
|
||||
*
|
||||
*/
|
||||
private function importForms() {
|
||||
$imported_forms_count = 0;
|
||||
if($this->importStopped()) {
|
||||
return;
|
||||
}
|
||||
$this->log(__("Importing forms...", 'mailpoet'));
|
||||
do {
|
||||
if($this->importStopped()) {
|
||||
break;
|
||||
}
|
||||
$forms = $this->getForms(self::CHUNK_SIZE);
|
||||
$forms_count = count($forms);
|
||||
|
||||
if(is_array($forms)) {
|
||||
foreach($forms as $form) {
|
||||
$new_form = $this->importForm($form);
|
||||
if(!empty($new_form)) {
|
||||
$imported_forms_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->progressbar->incrementCurrentCount($forms_count);
|
||||
} while(($forms != null) && ($forms_count > 0));
|
||||
|
||||
$this->log(sprintf(_n("%d form imported", "%d forms imported", $imported_forms_count, 'mailpoet'), $imported_forms_count));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Mailpoet 2 forms
|
||||
*
|
||||
* @global object $wpdb
|
||||
* @param int $limit Number of forms max
|
||||
* @return array Forms
|
||||
*/
|
||||
private function getForms($limit) {
|
||||
global $wpdb;
|
||||
$forms = array();
|
||||
|
||||
$last_id = Setting::getValue('last_imported_form_id', 0);
|
||||
$table = MP2_FORM_TABLE;
|
||||
$sql = "
|
||||
SELECT f.*
|
||||
FROM `$table` f
|
||||
WHERE f.form_id > '$last_id'
|
||||
ORDER BY f.form_id
|
||||
LIMIT $limit
|
||||
";
|
||||
$forms = $wpdb->get_results($sql, ARRAY_A);
|
||||
|
||||
return $forms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a form
|
||||
*
|
||||
* @param array $form_data Form data
|
||||
* @return Form
|
||||
*/
|
||||
private function importForm($form_data) {
|
||||
$serialized_data = base64_decode($form_data['data']);
|
||||
$data = unserialize($serialized_data);
|
||||
$settings = $data['settings'];
|
||||
$body = $data['body'];
|
||||
$segments = $this->getMappedSegmentIds($settings['lists']);
|
||||
$mp3_form_settings = array(
|
||||
'on_success' => $settings['on_success'],
|
||||
'success_message' => $settings['success_message'],
|
||||
'segments_selected_by' => $settings['lists_selected_by'],
|
||||
'segments' => $segments,
|
||||
);
|
||||
|
||||
$mp3_form_body = array();
|
||||
foreach($body as $field) {
|
||||
$type = $this->mapCustomFieldType($field['type']);
|
||||
if($type == 'segment') {
|
||||
$field_id = 'segments';
|
||||
} else {
|
||||
switch($field['field']) {
|
||||
case 'firstname':
|
||||
$field_id = 'first_name';
|
||||
break;
|
||||
case 'lastname':
|
||||
$field_id = 'last_name';
|
||||
break;
|
||||
default:
|
||||
$field_id = $field['field'];
|
||||
}
|
||||
}
|
||||
$field_id = preg_replace('/^cf_(\d+)$/', '$1', $field_id);
|
||||
$params = $this->mapCustomFieldParams($field['name'], $field['params']);
|
||||
if(isset($params['text'])) {
|
||||
$params['text'] = $this->replaceMP2Shortcodes(html_entity_decode($params['text']));
|
||||
}
|
||||
if(isset($params['values'])) {
|
||||
$params['values'] = $this->replaceListIds($params['values']);
|
||||
}
|
||||
$mp3_form_body[] = array(
|
||||
'type' => $type,
|
||||
'name' => $field['name'],
|
||||
'id' => $field_id,
|
||||
'unique' => !in_array($field['type'], array('html', 'divider', 'email', 'submit'))? "1" : "0",
|
||||
'static' => in_array($field_id, array('email', 'submit'))? "1" : "0",
|
||||
'params' => $params,
|
||||
'position' => isset($field['position'])? $field['position'] : '',
|
||||
);
|
||||
}
|
||||
|
||||
$form = Form::createOrUpdate(array(
|
||||
'name' => $form_data['name'],
|
||||
'body' => $mp3_form_body,
|
||||
'settings' => $mp3_form_settings,
|
||||
));
|
||||
Setting::setValue('last_imported_form_id', $form_data['form_id']);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the MP3 segments IDs of the MP2 lists IDs
|
||||
*
|
||||
* @param array $mp2_list_ids
|
||||
*/
|
||||
private function getMappedSegmentIds($mp2_list_ids) {
|
||||
$mp3_segment_ids = array();
|
||||
foreach($mp2_list_ids as $list_id) {
|
||||
if(isset($this->segments_mapping[$list_id])) {
|
||||
$mp3_segment_ids[] = $this->segments_mapping[$list_id];
|
||||
}
|
||||
}
|
||||
return $mp3_segment_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the MP2 shortcodes used in the textarea fields
|
||||
*
|
||||
* @param string $text Text
|
||||
* @return string Text
|
||||
*/
|
||||
private function replaceMP2Shortcodes($text) {
|
||||
$text = str_replace('[total_subscribers]', '[mailpoet_subscribers_count]', $text);
|
||||
$text = preg_replace_callback('/\[wysija_subscribers_count list_id="(.*)" \]/', array($this, 'replaceMP2ShortcodesCallback'), $text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for MP2 shortcodes replacement
|
||||
*
|
||||
* @param array $matches PREG matches
|
||||
* @return string Replacement
|
||||
*/
|
||||
private function replaceMP2ShortcodesCallback($matches) {
|
||||
if(!empty($matches)) {
|
||||
$mp2_lists = explode(',', $matches[1]);
|
||||
$segments = $this->getMappedSegmentIds($mp2_lists);
|
||||
$segments_ids = implode(',', $segments);
|
||||
return '[mailpoet_subscribers_count segments=' . $segments_ids . ']';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the MP2 list IDs by MP3 segment IDs
|
||||
*
|
||||
* @param array $values Field values
|
||||
* @return array Field values
|
||||
*/
|
||||
private function replaceListIds($values) {
|
||||
$mp3_values = array();
|
||||
foreach($values as $value) {
|
||||
$mp3_value = array();
|
||||
foreach($value as $item => $item_value) {
|
||||
if(($item == 'list_id') && isset($this->segments_mapping[$item_value])) {
|
||||
$segment_id = $this->segments_mapping[$item_value];
|
||||
$mp3_value['id'] = $segment_id;
|
||||
$segment = Segment::findOne($segment_id);
|
||||
if(isset($segment)) {
|
||||
$mp3_value['name'] = $segment->get('name');
|
||||
}
|
||||
} else {
|
||||
$mp3_value[$item] = $item_value;
|
||||
}
|
||||
}
|
||||
if(!empty($mp3_value)) {
|
||||
$mp3_values[] = $mp3_value;
|
||||
}
|
||||
}
|
||||
return $mp3_values;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ use MailPoet\Models\MappingToExternalEntities;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\SubscriberCustomField;
|
||||
use MailPoet\Models\SubscriberSegment;
|
||||
use MailPoet\Models\Form;
|
||||
use Helper\Database;
|
||||
|
||||
class MP2MigratorTest extends MailPoetTest {
|
||||
@@ -349,4 +349,151 @@ class MP2MigratorTest extends MailPoetTest {
|
||||
expect($result[$old_id])->equals($new_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the importForms function
|
||||
*
|
||||
* @global object $wpdb
|
||||
*/
|
||||
public function testImportForms() {
|
||||
global $wpdb;
|
||||
|
||||
// Check the forms number
|
||||
$this->initImport();
|
||||
$this->loadMP2Fixtures();
|
||||
$this->invokeMethod($this->MP2Migrator, 'importForms');
|
||||
expect(Form::count())->equals(2);
|
||||
|
||||
// Check a form data
|
||||
$this->initImport();
|
||||
$id = 999;
|
||||
$name = 'Test form';
|
||||
$list_id = 2;
|
||||
|
||||
// Insert a MP2 list
|
||||
$wpdb->insert($wpdb->prefix . 'wysija_list', array(
|
||||
'list_id' => $list_id,
|
||||
'name' => 'Test list',
|
||||
'description' => 'Test list description',
|
||||
'is_enabled' => 1,
|
||||
'is_public' => 1,
|
||||
'created_at' => 1486319877,
|
||||
));
|
||||
$this->invokeMethod($this->MP2Migrator, 'importSegments');
|
||||
$importedSegmentsMapping = $this->MP2Migrator->getImportedMapping('segments');
|
||||
|
||||
// Insert a MP2 form
|
||||
$data = array(
|
||||
'version' => 0.4,
|
||||
'settings' => array(
|
||||
'on_success' => 'message',
|
||||
'success_message' => 'Test message',
|
||||
'lists' => array($list_id),
|
||||
'lists_selected_by' => 'admin',
|
||||
),
|
||||
'body' => array(
|
||||
array(
|
||||
'name' => 'E-mail',
|
||||
'type' => 'input',
|
||||
'field' => 'email',
|
||||
'params' => array(
|
||||
'label' => 'E-mail',
|
||||
'required' => 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
$wpdb->insert($wpdb->prefix . 'wysija_form', array(
|
||||
'form_id' => $id,
|
||||
'name' => $name,
|
||||
'data' => base64_encode(serialize($data)),
|
||||
));
|
||||
$this->invokeMethod($this->MP2Migrator, 'importForms');
|
||||
$table = MP_FORMS_TABLE;
|
||||
$form = $wpdb->get_row("SELECT * FROM $table WHERE id=" . 1);
|
||||
expect($form->name)->equals($name);
|
||||
$settings = unserialize(($form->settings));
|
||||
expect($settings['on_success'])->equals('message');
|
||||
expect($settings['success_message'])->equals('Test message');
|
||||
expect($settings['segments'][0])->equals($importedSegmentsMapping[$list_id]);
|
||||
$body = unserialize(($form->body));
|
||||
expect($body[0]['name'])->equals('E-mail');
|
||||
expect($body[0]['type'])->equals('text');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the replaceMP2Shortcodes function
|
||||
*
|
||||
*/
|
||||
public function testReplaceMP2Shortcodes() {
|
||||
$this->initImport();
|
||||
|
||||
$result = $this->invokeMethod($this->MP2Migrator, 'replaceMP2Shortcodes', array('[total_subscribers]'));
|
||||
expect($result)->equals('[mailpoet_subscribers_count]');
|
||||
|
||||
$result = $this->invokeMethod($this->MP2Migrator, 'replaceMP2Shortcodes', array('Total: [total_subscribers]'));
|
||||
expect($result)->equals('Total: [mailpoet_subscribers_count]');
|
||||
|
||||
$result = $this->invokeMethod($this->MP2Migrator, 'replaceMP2Shortcodes', array('Total: [total_subscribers] found'));
|
||||
expect($result)->equals('Total: [mailpoet_subscribers_count] found');
|
||||
|
||||
$result = $this->invokeMethod($this->MP2Migrator, 'replaceMP2Shortcodes', array('[wysija_subscribers_count list_id="1,2" ]'));
|
||||
expect($result)->notEquals('mailpoet_subscribers_count segments=1,2');
|
||||
|
||||
$this->loadMP2Fixtures();
|
||||
$this->invokeMethod($this->MP2Migrator, 'importSegments');
|
||||
$result = $this->invokeMethod($this->MP2Migrator, 'replaceMP2Shortcodes', array('[wysija_subscribers_count list_id="1,2" ]'));
|
||||
$importedSegmentsMapping = $this->MP2Migrator->getImportedMapping('segments');
|
||||
expect($result)->equals(sprintf('[mailpoet_subscribers_count segments=%d,%d]', $importedSegmentsMapping[1], $importedSegmentsMapping[2]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the getMappedSegmentIds function
|
||||
*
|
||||
*/
|
||||
public function testGetMappedSegmentIds() {
|
||||
$this->initImport();
|
||||
|
||||
$lists = array(1, 2);
|
||||
$this->loadMP2Fixtures();
|
||||
$this->invokeMethod($this->MP2Migrator, 'importSegments');
|
||||
$importedSegmentsMapping = $this->MP2Migrator->getImportedMapping('segments');
|
||||
$result = $this->invokeMethod($this->MP2Migrator, 'getMappedSegmentIds', array($lists));
|
||||
$expected_lists = array($importedSegmentsMapping[1],$importedSegmentsMapping[2]);
|
||||
expect($result)->equals($expected_lists);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the replaceListIds function
|
||||
*
|
||||
*/
|
||||
public function testReplaceListIds() {
|
||||
$this->initImport();
|
||||
|
||||
$lists = array(
|
||||
array(
|
||||
'list_id' => 1,
|
||||
'name' => 'List 1',
|
||||
),
|
||||
array(
|
||||
'list_id' => 2,
|
||||
'name' => 'List 2',
|
||||
),
|
||||
);
|
||||
$this->loadMP2Fixtures();
|
||||
$this->invokeMethod($this->MP2Migrator, 'importSegments');
|
||||
$importedSegmentsMapping = $this->MP2Migrator->getImportedMapping('segments');
|
||||
$result = $this->invokeMethod($this->MP2Migrator, 'replaceListIds', array($lists));
|
||||
$expected_lists = array(
|
||||
array(
|
||||
'id' => $importedSegmentsMapping[1],
|
||||
'name' => 'List 1',
|
||||
),
|
||||
array(
|
||||
'id' => $importedSegmentsMapping[2],
|
||||
'name' => 'List 2',
|
||||
),
|
||||
);
|
||||
expect($result)->equals($expected_lists);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -10,8 +10,8 @@
|
||||
<h3><%= __('What will be kept in MailPoet 3') %></h3>
|
||||
<ul>
|
||||
<li><strong><%= __('Subscribers and lists') %> <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/2.2.1/svg/2714.svg"></strong></li>
|
||||
<li><strong><%= __('Forms') %> <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/2.2.1/svg/2714.svg"></strong></li>
|
||||
<li><%= __('Settings') %> (<%= __('soon') %>!)</li>
|
||||
<li><%= __('Forms') %> (<%= __('soon') %>!)</li>
|
||||
<li><%= __('Archive of sent newsletters') %> (<%= __('soon') %>!)</li>
|
||||
</ul>
|
||||
|
||||
|
Reference in New Issue
Block a user