- Removes file size limit in import
- Implements chunked import processing - Updates tests/migrator/Subscriber model
This commit is contained in:
@ -6,7 +6,8 @@ define(
|
|||||||
'mailpoet',
|
'mailpoet',
|
||||||
'handlebars',
|
'handlebars',
|
||||||
'papaparse',
|
'papaparse',
|
||||||
'select2'
|
'select2',
|
||||||
|
'asyncqueue'
|
||||||
],
|
],
|
||||||
function (
|
function (
|
||||||
Backbone,
|
Backbone,
|
||||||
@ -14,12 +15,14 @@ define(
|
|||||||
jQuery,
|
jQuery,
|
||||||
MailPoet,
|
MailPoet,
|
||||||
Handlebars,
|
Handlebars,
|
||||||
Papa
|
Papa,
|
||||||
|
AsyncQueue
|
||||||
) {
|
) {
|
||||||
if (!jQuery('#mailpoet_subscribers_import').length) {
|
if (!jQuery('#mailpoet_subscribers_import').length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
jQuery(document).ready(function () {
|
jQuery(document).ready(function () {
|
||||||
|
console.log = function() {};
|
||||||
jQuery('input[name="select_method"]').attr('checked', false);
|
jQuery('input[name="select_method"]').attr('checked', false);
|
||||||
// configure router
|
// configure router
|
||||||
router = new (Backbone.Router.extend({
|
router = new (Backbone.Router.extend({
|
||||||
@ -1050,64 +1053,96 @@ define(
|
|||||||
}
|
}
|
||||||
MailPoet.Modal.loading(true);
|
MailPoet.Modal.loading(true);
|
||||||
|
|
||||||
var subscribers = {};
|
var columns = {},
|
||||||
|
queue = new jQuery.AsyncQueue(),
|
||||||
|
batch = 0,
|
||||||
|
subscribers = [],
|
||||||
|
importResults = {
|
||||||
|
'created': 0,
|
||||||
|
'updated': 0,
|
||||||
|
'errors': [],
|
||||||
|
'segments': []
|
||||||
|
},
|
||||||
|
splitSubscribers = function (subscribers, size) {
|
||||||
|
return subscribers.reduce(function (res, item, index) {
|
||||||
|
if (index % size === 0) {
|
||||||
|
res.push([]);
|
||||||
|
}
|
||||||
|
res[res.length - 1].push(item);
|
||||||
|
return res;
|
||||||
|
}, []);
|
||||||
|
},
|
||||||
|
subscribers = splitSubscribers(importData.step1.subscribers, 500);
|
||||||
|
|
||||||
_.each(jQuery('select.mailpoet_subscribers_column_data_match'),
|
_.each(jQuery('select.mailpoet_subscribers_column_data_match'),
|
||||||
function (column, index) {
|
function (column, columnIndex) {
|
||||||
var columnId = jQuery(column).data('column-id');
|
var columnId = jQuery(column).data('column-id');
|
||||||
if (columnId === 'ignore') {
|
if (columnId === 'ignore') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
subscribers[columnId] = [];
|
columns[columnId] = columnIndex;
|
||||||
_.each(importData.step1.subscribers, function (subsciber) {
|
});
|
||||||
subscribers[columnId].push(
|
|
||||||
_.chain(subsciber)
|
|
||||||
.pick(index)
|
|
||||||
.toArray()
|
|
||||||
.flatten()
|
|
||||||
.value()
|
|
||||||
);
|
|
||||||
});
|
|
||||||
subscribers[columnId] = _.flatten(subscribers[columnId]);
|
|
||||||
});
|
|
||||||
|
|
||||||
MailPoet.Ajax.post({
|
_.each(subscribers, function () {
|
||||||
endpoint: 'ImportExport',
|
queue.add(function (queue) {
|
||||||
action: 'processImport',
|
queue.pause();
|
||||||
data: JSON.stringify({
|
MailPoet.Ajax
|
||||||
subscribers: subscribers,
|
.post({
|
||||||
segments: segmentSelectElement.val(),
|
endpoint: 'ImportExport',
|
||||||
updateSubscribers: (jQuery(':radio[name="subscriber_update_option"]:checked').val() === 'yes') ? true : false
|
action: 'processImport',
|
||||||
|
data: JSON.stringify({
|
||||||
|
columns: columns,
|
||||||
|
subscribers: subscribers[batch],
|
||||||
|
length: subscribers[batch].length,
|
||||||
|
segments: segmentSelectElement.val(),
|
||||||
|
updateSubscribers: (jQuery(':radio[name="subscriber_update_option"]:checked').val() === 'yes') ? true : false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.done(function (response) {
|
||||||
|
if (response.result === false) {
|
||||||
|
importResults.errors.push(response.errors);
|
||||||
|
} else {
|
||||||
|
importResults.created += response.data.created;
|
||||||
|
importResults.updated += response.data.updated;
|
||||||
|
importResults.segments = response.data.segments;
|
||||||
|
}
|
||||||
|
queue.run();
|
||||||
|
})
|
||||||
|
.error(function (error) {
|
||||||
|
importResults.errors.push(
|
||||||
|
MailPoetI18n.serverError + error.statusText.toLowerCase() + '.'
|
||||||
|
);
|
||||||
|
queue.run();
|
||||||
|
});
|
||||||
|
batch++;
|
||||||
})
|
})
|
||||||
}).done(function (response) {
|
});
|
||||||
|
|
||||||
|
queue.run();
|
||||||
|
|
||||||
|
queue.onComplete(function () {
|
||||||
MailPoet.Modal.loading(false);
|
MailPoet.Modal.loading(false);
|
||||||
if (response.result === false) {
|
if (importResults.errors.length > 0 && !importResults.updated && !importResults.created) {
|
||||||
MailPoet.Notice.error(response.errors, {
|
MailPoet.Notice.error(_.flatten(importResults.errors), {
|
||||||
timeout: 3000,
|
timeout: 3000,
|
||||||
});
|
}
|
||||||
} else {
|
);
|
||||||
mailpoetSegments = response.data.segments;
|
}
|
||||||
response.data.segments = _.map(segmentSelectElement.select2('data'),
|
else {
|
||||||
function (data) {
|
mailpoetSegments = importResults.segments;
|
||||||
return data.name;
|
importResults.segments = _.map(segmentSelectElement.select2('data'),
|
||||||
});
|
function (data) {
|
||||||
importData.step2 = response.data;
|
return data.name;
|
||||||
|
});
|
||||||
|
importData.step2 = importResults;
|
||||||
enableSegmentSelection(mailpoetSegments);
|
enableSegmentSelection(mailpoetSegments);
|
||||||
router.navigate('step3', {trigger: true});
|
router.navigate('step3', {trigger: true});
|
||||||
}
|
}
|
||||||
}).error(function (error) {
|
|
||||||
MailPoet.Modal.loading(false);
|
|
||||||
MailPoet.Notice.error(
|
|
||||||
MailPoetI18n.serverError + error.statusText.toLowerCase() + '.', {
|
|
||||||
timeout: 3000,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
filterSubscribers();
|
filterSubscribers();
|
||||||
enableSegmentSelection(mailpoetSegments);
|
enableSegmentSelection(mailpoetSegments);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.on('route:step3', function () {
|
router.on('route:step3', function () {
|
||||||
@ -1118,6 +1153,12 @@ define(
|
|||||||
|
|
||||||
showCurrentStep();
|
showCurrentStep();
|
||||||
|
|
||||||
|
if (importData.step2.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(_.flatten(importData.step2.errors), {
|
||||||
|
timeout: 3000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// display statistics
|
// display statistics
|
||||||
var subscribersDataImportResultsTemplate =
|
var subscribersDataImportResultsTemplate =
|
||||||
Handlebars
|
Handlebars
|
||||||
|
@ -57,6 +57,7 @@ class Migrator {
|
|||||||
'last_name tinytext NOT NULL,',
|
'last_name tinytext NOT NULL,',
|
||||||
'email varchar(150) NOT NULL,',
|
'email varchar(150) NOT NULL,',
|
||||||
'status varchar(12) NOT NULL DEFAULT "unconfirmed",',
|
'status varchar(12) NOT NULL DEFAULT "unconfirmed",',
|
||||||
|
'import_batch varchar(12) NULL,',
|
||||||
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
|
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
|
||||||
'deleted_at TIMESTAMP NULL DEFAULT NULL,',
|
'deleted_at TIMESTAMP NULL DEFAULT NULL,',
|
||||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||||
|
@ -498,7 +498,7 @@ class Subscriber extends Model {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function updateMultiple($columns, $subscribers, $currentTime = false) {
|
static function updateMultiple($columns, $subscribers, $import_batch = false) {
|
||||||
$ignoreColumnsOnUpdate = array(
|
$ignoreColumnsOnUpdate = array(
|
||||||
'email',
|
'email',
|
||||||
'created_at'
|
'created_at'
|
||||||
@ -538,7 +538,7 @@ class Subscriber extends Model {
|
|||||||
return self::rawExecute(
|
return self::rawExecute(
|
||||||
'UPDATE `' . self::$_table . '` ' .
|
'UPDATE `' . self::$_table . '` ' .
|
||||||
'SET ' . implode(', ', $sql('statement')) . ' '.
|
'SET ' . implode(', ', $sql('statement')) . ' '.
|
||||||
(($currentTime) ? ', updated_at = "' . $currentTime . '" ' : '') .
|
(($import_batch) ? ', import_batch = "' . $import_batch . '" ' : '') .
|
||||||
'WHERE email IN ' .
|
'WHERE email IN ' .
|
||||||
'(' . rtrim(str_repeat('?,', count($subscribers)), ',') . ')',
|
'(' . rtrim(str_repeat('?,', count($subscribers)), ',') . ')',
|
||||||
array_merge(
|
array_merge(
|
||||||
|
@ -6,6 +6,7 @@ use MailPoet\Models\SubscriberCustomField;
|
|||||||
use MailPoet\Models\SubscriberSegment;
|
use MailPoet\Models\SubscriberSegment;
|
||||||
use MailPoet\Subscribers\ImportExport\BootStrapMenu;
|
use MailPoet\Subscribers\ImportExport\BootStrapMenu;
|
||||||
use MailPoet\Util\Helpers;
|
use MailPoet\Util\Helpers;
|
||||||
|
use MailPoet\Util\Security;
|
||||||
|
|
||||||
class Import {
|
class Import {
|
||||||
public $subscribers_data;
|
public $subscribers_data;
|
||||||
@ -15,20 +16,25 @@ class Import {
|
|||||||
public $subscriber_custom_fields;
|
public $subscriber_custom_fields;
|
||||||
public $subscribers_count;
|
public $subscribers_count;
|
||||||
public $import_time;
|
public $import_time;
|
||||||
|
public $import_batch;
|
||||||
public $profiler_start;
|
public $profiler_start;
|
||||||
|
|
||||||
public function __construct($data) {
|
public function __construct($data) {
|
||||||
$this->subscribers_data = $data['subscribers'];
|
$this->subscribers_data = $this->transformSubscribersData(
|
||||||
|
$data['subscribers'],
|
||||||
|
$data['columns']
|
||||||
|
);
|
||||||
$this->segments = $data['segments'];
|
$this->segments = $data['segments'];
|
||||||
$this->update_subscribers = $data['updateSubscribers'];
|
$this->update_subscribers = $data['updateSubscribers'];
|
||||||
$this->subscriber_fields = $this->getSubscriberFields(
|
$this->subscriber_fields = $this->getSubscriberFields(
|
||||||
array_keys($this->subscribers_data)
|
array_keys($data['columns'])
|
||||||
);
|
);
|
||||||
$this->subscriber_custom_fields = $this->getCustomSubscriberFields(
|
$this->subscriber_custom_fields = $this->getCustomSubscriberFields(
|
||||||
array_keys($this->subscribers_data)
|
array_keys($data['columns'])
|
||||||
);
|
);
|
||||||
$this->subscribers_count = count(reset($this->subscribers_data));
|
$this->subscribers_count = count(reset($this->subscribers_data));
|
||||||
$this->import_time = date('Y-m-d H:i:s');
|
$this->import_time = date('Y-m-d H:i:s');
|
||||||
|
$this->import_batch = Security::generateRandomString();
|
||||||
$this->profiler_start = microtime(true);
|
$this->profiler_start = microtime(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,14 +69,6 @@ class Import {
|
|||||||
$subscriber_fields,
|
$subscriber_fields,
|
||||||
$subscriber_custom_fields
|
$subscriber_custom_fields
|
||||||
);
|
);
|
||||||
if($created_subscribers) {
|
|
||||||
// subtract added from updated subscribers when DB operation takes <1s
|
|
||||||
$updated_subscribers = array_diff_key(
|
|
||||||
$updated_subscribers,
|
|
||||||
$created_subscribers,
|
|
||||||
$subscriber_custom_fields
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch(\PDOException $e) {
|
} catch(\PDOException $e) {
|
||||||
return array(
|
return array(
|
||||||
@ -86,13 +84,21 @@ class Import {
|
|||||||
'updated' => count($updated_subscribers),
|
'updated' => count($updated_subscribers),
|
||||||
'segments' => $segments->getSegments()
|
'segments' => $segments->getSegments()
|
||||||
),
|
),
|
||||||
|
'time' => date('Y-m-d H:i:s'),
|
||||||
'profiler' => $this->timeExecution()
|
'profiler' => $this->timeExecution()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function transformSubscribersData($subscribers, $columns) {
|
||||||
|
foreach($columns as $column => $index) {
|
||||||
|
$transformed_subscribers[$column] = Helpers::arrayColumn($subscribers, $index);
|
||||||
|
}
|
||||||
|
return $transformed_subscribers;
|
||||||
|
}
|
||||||
|
|
||||||
function filterExistingAndNewSubscribers($subscribers_data) {
|
function filterExistingAndNewSubscribers($subscribers_data) {
|
||||||
$existing_records = array_filter(
|
$existing_records = array_filter(
|
||||||
array_map(function($subscriber_emails) {
|
array_map(function ($subscriber_emails) {
|
||||||
return Subscriber::selectMany(array('email'))
|
return Subscriber::selectMany(array('email'))
|
||||||
->whereIn('email', $subscriber_emails)
|
->whereIn('email', $subscriber_emails)
|
||||||
->whereNull('deleted_at')
|
->whereNull('deleted_at')
|
||||||
@ -120,18 +126,18 @@ class Import {
|
|||||||
}
|
}
|
||||||
$new_subscribers =
|
$new_subscribers =
|
||||||
array_filter(
|
array_filter(
|
||||||
array_map(function($subscriber) use ($new_records) {
|
array_map(function ($subscriber) use ($new_records) {
|
||||||
return array_map(function($index) use ($subscriber) {
|
return array_map(function ($index) use ($subscriber) {
|
||||||
return $subscriber[$index];
|
return $subscriber[$index];
|
||||||
}, $new_records);
|
}, $new_records);
|
||||||
}, $subscribers_data)
|
}, $subscribers_data)
|
||||||
);
|
);
|
||||||
|
|
||||||
$existing_subscribers =
|
$existing_subscribers =
|
||||||
array_map(function($subscriber) use ($new_records) {
|
array_map(function ($subscriber) use ($new_records) {
|
||||||
return array_values( // reindex array
|
return array_values( // reindex array
|
||||||
array_filter( // remove NULL entries
|
array_filter( // remove NULL entries
|
||||||
array_map(function($index, $data) use ($new_records) {
|
array_map(function ($index, $data) use ($new_records) {
|
||||||
if(!in_array($index, $new_records)) return $data;
|
if(!in_array($index, $new_records)) return $data;
|
||||||
}, array_keys($subscriber), $subscriber)
|
}, array_keys($subscriber), $subscriber)
|
||||||
)
|
)
|
||||||
@ -145,7 +151,7 @@ class Import {
|
|||||||
|
|
||||||
function deleteExistingTrashedSubscribers($subscribers_data) {
|
function deleteExistingTrashedSubscribers($subscribers_data) {
|
||||||
$existing_trashed_records = array_filter(
|
$existing_trashed_records = array_filter(
|
||||||
array_map(function($subscriber_emails) {
|
array_map(function ($subscriber_emails) {
|
||||||
return Subscriber::selectMany(array('id'))
|
return Subscriber::selectMany(array('id'))
|
||||||
->whereIn('email', $subscriber_emails)
|
->whereIn('email', $subscriber_emails)
|
||||||
->whereNotNull('deleted_at')
|
->whereNotNull('deleted_at')
|
||||||
@ -163,8 +169,17 @@ class Import {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function extendSubscribersAndFields($subscribers_data, $subscriber_fields) {
|
function extendSubscribersAndFields($subscribers_data, $subscriber_fields) {
|
||||||
$subscribers_data['created_at'] = $this->filterSubscriberCreatedAtDate();
|
$subscribers_data['created_at'] =
|
||||||
$subscriber_fields[] = 'created_at';
|
array_fill(0, $this->subscribers_count, $this->import_time);
|
||||||
|
$subscribers_data['import_batch'] =
|
||||||
|
array_fill(0, $this->subscribers_count, $this->import_batch);
|
||||||
|
$subscriber_fields = array_merge(
|
||||||
|
$subscriber_fields,
|
||||||
|
array(
|
||||||
|
'created_at',
|
||||||
|
'import_batch'
|
||||||
|
)
|
||||||
|
);
|
||||||
return array(
|
return array(
|
||||||
$subscribers_data,
|
$subscribers_data,
|
||||||
$subscriber_fields
|
$subscriber_fields
|
||||||
@ -174,7 +189,7 @@ class Import {
|
|||||||
function getSubscriberFields($subscriber_fields) {
|
function getSubscriberFields($subscriber_fields) {
|
||||||
return array_values(
|
return array_values(
|
||||||
array_filter(
|
array_filter(
|
||||||
array_map(function($field) {
|
array_map(function ($field) {
|
||||||
if(!is_int($field)) return $field;
|
if(!is_int($field)) return $field;
|
||||||
}, $subscriber_fields)
|
}, $subscriber_fields)
|
||||||
)
|
)
|
||||||
@ -184,17 +199,13 @@ class Import {
|
|||||||
function getCustomSubscriberFields($subscriber_fields) {
|
function getCustomSubscriberFields($subscriber_fields) {
|
||||||
return array_values(
|
return array_values(
|
||||||
array_filter(
|
array_filter(
|
||||||
array_map(function($field) {
|
array_map(function ($field) {
|
||||||
if(is_int($field)) return $field;
|
if(is_int($field)) return $field;
|
||||||
}, $subscriber_fields)
|
}, $subscriber_fields)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterSubscriberCreatedAtDate() {
|
|
||||||
return array_fill(0, $this->subscribers_count, $this->import_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterSubscriberStatus($subscribers_data, $subscriber_fields) {
|
function filterSubscriberStatus($subscribers_data, $subscriber_fields) {
|
||||||
if(!in_array('status', $subscriber_fields)) {
|
if(!in_array('status', $subscriber_fields)) {
|
||||||
$subscribers_data['status'] =
|
$subscribers_data['status'] =
|
||||||
@ -225,7 +236,7 @@ class Import {
|
|||||||
'false'
|
'false'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$subscribers_data['status'] = array_map(function($state) use ($statuses) {
|
$subscribers_data['status'] = array_map(function ($state) use ($statuses) {
|
||||||
if(in_array(strtolower($state), $statuses['subscribed'])) {
|
if(in_array(strtolower($state), $statuses['subscribed'])) {
|
||||||
return 'subscribed';
|
return 'subscribed';
|
||||||
}
|
}
|
||||||
@ -250,12 +261,12 @@ class Import {
|
|||||||
$subscriber_custom_fields
|
$subscriber_custom_fields
|
||||||
) {
|
) {
|
||||||
$subscribers_count = count(reset($subscribers_data)) - 1;
|
$subscribers_count = count(reset($subscribers_data)) - 1;
|
||||||
$subscribers = array_map(function($index) use ($subscribers_data, $subscriber_fields) {
|
$subscribers = array_map(function ($index) use ($subscribers_data, $subscriber_fields) {
|
||||||
return array_map(function($field) use ($index, $subscribers_data) {
|
return array_map(function ($field) use ($index, $subscribers_data) {
|
||||||
return $subscribers_data[$field][$index];
|
return $subscribers_data[$field][$index];
|
||||||
}, $subscriber_fields);
|
}, $subscriber_fields);
|
||||||
}, range(0, $subscribers_count));
|
}, range(0, $subscribers_count));
|
||||||
$import_time = ($action === 'update') ? date('Y-m-d H:i:s') : $this->import_time;
|
$batch = ($action === 'update') ? Security::generateRandomString() : $this->import_batch;
|
||||||
foreach(array_chunk($subscribers, 100) as $data) {
|
foreach(array_chunk($subscribers, 100) as $data) {
|
||||||
if($action == 'create') {
|
if($action == 'create') {
|
||||||
Subscriber::createMultiple(
|
Subscriber::createMultiple(
|
||||||
@ -267,7 +278,7 @@ class Import {
|
|||||||
Subscriber::updateMultiple(
|
Subscriber::updateMultiple(
|
||||||
$subscriber_fields,
|
$subscriber_fields,
|
||||||
$data,
|
$data,
|
||||||
$import_time
|
$batch
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,7 +288,7 @@ class Import {
|
|||||||
'id',
|
'id',
|
||||||
'email'
|
'email'
|
||||||
))
|
))
|
||||||
->where(($action === 'create') ? 'created_at' : 'updated_at', $import_time)
|
->where('import_batch', $batch)
|
||||||
->findArray(),
|
->findArray(),
|
||||||
'email', 'id'
|
'email', 'id'
|
||||||
);
|
);
|
||||||
@ -303,10 +314,10 @@ class Import {
|
|||||||
$subscriber_custom_fields
|
$subscriber_custom_fields
|
||||||
) {
|
) {
|
||||||
$subscribers = array_map(
|
$subscribers = array_map(
|
||||||
function($column) use ($db_subscribers, $subscribers_data) {
|
function ($column) use ($db_subscribers, $subscribers_data) {
|
||||||
$count = range(0, count($subscribers_data[$column]) - 1);
|
$count = range(0, count($subscribers_data[$column]) - 1);
|
||||||
return array_map(
|
return array_map(
|
||||||
function($index, $value)
|
function ($index, $value)
|
||||||
use ($db_subscribers, $subscribers_data, $column) {
|
use ($db_subscribers, $subscribers_data, $column) {
|
||||||
$subscriber_id = array_search(
|
$subscriber_id = array_search(
|
||||||
$subscribers_data['email'][$index],
|
$subscribers_data['email'][$index],
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
},
|
},
|
||||||
"napa": {
|
"napa": {
|
||||||
"blob": "eligrey/Blob.js.git",
|
"blob": "eligrey/Blob.js.git",
|
||||||
"filesaver": "eligrey/FileSaver.js.git"
|
"filesaver": "eligrey/FileSaver.js.git",
|
||||||
|
"asyncqueue": "mjward/Jquery-Async-queue.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"backbone": "1.2.3",
|
"backbone": "1.2.3",
|
||||||
|
@ -8,24 +8,31 @@ use MailPoet\Util\Helpers;
|
|||||||
|
|
||||||
class ImportCest {
|
class ImportCest {
|
||||||
function __construct() {
|
function __construct() {
|
||||||
$this->JSON_data = json_decode(file_get_contents(dirname(__FILE__) . '/ImportTestData.json'), true);
|
$this->data = array(
|
||||||
$this->subscribers_data = array(
|
'subscribers' => array(
|
||||||
'first_name' => array(
|
array(
|
||||||
'Adam',
|
'Adam',
|
||||||
'Mary'
|
'Smith',
|
||||||
|
'adam@smith.com',
|
||||||
|
'France'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'Mary',
|
||||||
|
'Jane',
|
||||||
|
'mary@jane.com',
|
||||||
|
'Brazil'
|
||||||
|
)
|
||||||
),
|
),
|
||||||
'last_name' => array(
|
'columns' => array(
|
||||||
'Smith',
|
'first_name' => 0,
|
||||||
'Jane'
|
'last_name' => 1,
|
||||||
|
'email' => 2,
|
||||||
|
777 => 3
|
||||||
),
|
),
|
||||||
'email' => array(
|
'segments' => array(
|
||||||
'adam@smith.com',
|
195
|
||||||
'mary@jane.com'
|
|
||||||
),
|
),
|
||||||
777 => array(
|
'updateSubscribers' => true
|
||||||
'France',
|
|
||||||
'Brazil'
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
$this->subscriber_fields = array(
|
$this->subscriber_fields = array(
|
||||||
'first_name',
|
'first_name',
|
||||||
@ -34,25 +41,37 @@ class ImportCest {
|
|||||||
);
|
);
|
||||||
$this->segments = range(0, 1);
|
$this->segments = range(0, 1);
|
||||||
$this->subscriber_custom_fields = array(777);
|
$this->subscriber_custom_fields = array(777);
|
||||||
$this->import = new Import($this->JSON_data);
|
$this->import = new Import($this->data);
|
||||||
|
$this->subscribers_data = $this->import->transformSubscribersData(
|
||||||
|
$this->data['subscribers'],
|
||||||
|
$this->data['columns']
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function itCanConstruct() {
|
function itCanConstruct() {
|
||||||
expect($this->import->subscribers_data)->equals($this->JSON_data['subscribers']);
|
expect(is_array($this->import->subscribers_data))->true();
|
||||||
expect($this->import->segments)->equals($this->JSON_data['segments']);
|
expect($this->import->segments)->equals($this->data['segments']);
|
||||||
expect(is_array($this->import->subscriber_fields))->true();
|
expect(is_array($this->import->subscriber_fields))->true();
|
||||||
expect(is_array($this->import->subscriber_custom_fields))->true();
|
expect(is_array($this->import->subscriber_custom_fields))->true();
|
||||||
expect($this->import->subscribers_count)->equals(
|
expect($this->import->subscribers_count)->equals(2);
|
||||||
count($this->JSON_data['subscribers']['email'])
|
expect($this->import->import_batch)->notEmpty();
|
||||||
);
|
expect($this->import->import_time)->notEmpty();
|
||||||
expect(
|
expect($this->import->import_batch)->notEmpty();
|
||||||
preg_match(
|
}
|
||||||
'/\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}/',
|
|
||||||
$this->import->import_time)
|
function itCanTransformSubscribers() {
|
||||||
)->equals(1);
|
expect($this->import->subscribers_data['first_name'][0])
|
||||||
|
->equals($this->data['subscribers'][0][0]);
|
||||||
|
expect($this->import->subscribers_data['last_name'][0])
|
||||||
|
->equals($this->data['subscribers'][0][1]);
|
||||||
|
expect($this->import->subscribers_data['email'][0])
|
||||||
|
->equals($this->data['subscribers'][0][2]);
|
||||||
|
expect($this->import->subscribers_data['777'][0])
|
||||||
|
->equals($this->data['subscribers'][0][3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function itCanFilterExistingAndNewSubscribers() {
|
function itCanFilterExistingAndNewSubscribers() {
|
||||||
|
$subscribers_data = $this->subscribers_data;
|
||||||
$subscriber = Subscriber::create();
|
$subscriber = Subscriber::create();
|
||||||
$subscriber->hydrate(
|
$subscriber->hydrate(
|
||||||
array(
|
array(
|
||||||
@ -62,10 +81,10 @@ class ImportCest {
|
|||||||
));
|
));
|
||||||
$subscriber->save();
|
$subscriber->save();
|
||||||
list($existing, $new) = $this->import->filterExistingAndNewSubscribers(
|
list($existing, $new) = $this->import->filterExistingAndNewSubscribers(
|
||||||
$this->subscribers_data
|
$subscribers_data
|
||||||
);
|
);
|
||||||
expect($existing['email'][0])->equals($this->subscribers_data['email'][0]);
|
expect($existing['email'][0])->equals($subscribers_data['email'][0]);
|
||||||
expect($new['email'][0])->equals($this->subscribers_data['email'][1]);
|
expect($new['email'][0])->equals($subscribers_data['email'][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function itCanExtendSubscribersAndFields() {
|
function itCanExtendSubscribersAndFields() {
|
||||||
@ -106,17 +125,17 @@ class ImportCest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function itCanFilterSubscriberStatus() {
|
function itCanFilterSubscriberStatus() {
|
||||||
$subscibers_data = $this->subscribers_data;
|
$subscribers_data = $this->subscribers_data;
|
||||||
$subscriber_fields = $this->subscriber_fields;
|
$subscriber_fields = $this->subscriber_fields;
|
||||||
list($subscibers_data, $subsciber_fields) =
|
list($subscribers_data, $subsciber_fields) =
|
||||||
$this->import->filterSubscriberStatus($subscibers_data, $subscriber_fields);
|
$this->import->filterSubscriberStatus($subscribers_data, $subscriber_fields);
|
||||||
// subscribers' status was set to "subscribed" & status column was added
|
// subscribers' status was set to "subscribed" & status column was added
|
||||||
// to subscribers fields
|
// to subscribers fields
|
||||||
expect(array_pop($subsciber_fields))->equals('status');
|
expect(array_pop($subsciber_fields))->equals('status');
|
||||||
expect($subscibers_data['status'][0])->equals('subscribed');
|
expect($subscribers_data['status'][0])->equals('subscribed');
|
||||||
expect(count($subscibers_data['status']))->equals(2);
|
expect(count($subscribers_data['status']))->equals(2);
|
||||||
$subscriber_fields[] = 'status';
|
$subscriber_fields[] = 'status';
|
||||||
$subscibers_data = array(
|
$subscribers_data = array(
|
||||||
'status' => array(
|
'status' => array(
|
||||||
#subscribed
|
#subscribed
|
||||||
'subscribed',
|
'subscribed',
|
||||||
@ -135,9 +154,9 @@ class ImportCest {
|
|||||||
'false'
|
'false'
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
list($subscibers_data, $subsciber_fields) =
|
list($subscribers_data, $subsciber_fields) =
|
||||||
$this->import->filterSubscriberStatus($subscibers_data, $subscriber_fields);
|
$this->import->filterSubscriberStatus($subscribers_data, $subscriber_fields);
|
||||||
expect($subscibers_data)->equals(
|
expect($subscribers_data)->equals(
|
||||||
array(
|
array(
|
||||||
'status' => array(
|
'status' => array(
|
||||||
'subscribed',
|
'subscribed',
|
||||||
@ -185,8 +204,8 @@ class ImportCest {
|
|||||||
$subscribers_data = $this->subscribers_data;
|
$subscribers_data = $this->subscribers_data;
|
||||||
$subscriber_fields = $this->subscriber_fields;
|
$subscriber_fields = $this->subscriber_fields;
|
||||||
$subscribers_data['deleted_at'] = array(
|
$subscribers_data['deleted_at'] = array(
|
||||||
null,
|
null,
|
||||||
date('Y-m-d H:i:s')
|
date('Y-m-d H:i:s')
|
||||||
);
|
);
|
||||||
$subscriber_fields[] = 'deleted_at';
|
$subscriber_fields[] = 'deleted_at';
|
||||||
$this->import->createOrUpdateSubscribers(
|
$this->import->createOrUpdateSubscribers(
|
||||||
@ -255,6 +274,7 @@ class ImportCest {
|
|||||||
->equals($subscribers_data[777][1]);
|
->equals($subscribers_data[777][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function itCanaddSubscribersToSegments() {
|
function itCanaddSubscribersToSegments() {
|
||||||
$subscribers_data = $this->subscribers_data;
|
$subscribers_data = $this->subscribers_data;
|
||||||
$this->import->createOrUpdateSubscribers(
|
$this->import->createOrUpdateSubscribers(
|
||||||
@ -296,19 +316,17 @@ class ImportCest {
|
|||||||
function itCanProcess() {
|
function itCanProcess() {
|
||||||
$import = clone($this->import);
|
$import = clone($this->import);
|
||||||
$result = $import->process();
|
$result = $import->process();
|
||||||
expect($result['data']['created'])->equals(997);
|
expect($result['data']['created'])->equals(2);
|
||||||
expect($result['data']['updated'])->equals(0);
|
expect($result['data']['updated'])->equals(0);
|
||||||
$result = $import->process();
|
$result = $import->process();
|
||||||
expect($result['data']['created'])->equals(0);
|
expect($result['data']['created'])->equals(0);
|
||||||
expect($result['data']['updated'])->equals(997);
|
expect($result['data']['updated'])->equals(2);
|
||||||
Subscriber::where('email', 'mbanks4@blinklist.com')
|
Subscriber::where('email', 'mary@jane.com')
|
||||||
->findOne()
|
->findOne()
|
||||||
->delete();
|
->delete();
|
||||||
// TODO: find a more elegant way to test this
|
|
||||||
$import->import_time = date('Y-m-d 12:i:s');
|
|
||||||
$result = $import->process();
|
$result = $import->process();
|
||||||
expect($result['data']['created'])->equals(1);
|
expect($result['data']['created'])->equals(1);
|
||||||
expect($result['data']['updated'])->equals(996);
|
expect($result['data']['updated'])->equals(1);
|
||||||
$import->update_subscribers = false;
|
$import->update_subscribers = false;
|
||||||
$result = $import->process();
|
$result = $import->process();
|
||||||
expect($result['data']['created'])->equals(0);
|
expect($result['data']['created'])->equals(0);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -60,8 +60,6 @@
|
|||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="file" id="file_local" accept=".csv" />
|
<input type="file" id="file_local" accept=".csv" />
|
||||||
|
|
||||||
<%= __('total max upload file size : %s')|format(maxPostSize) %>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -30,7 +30,8 @@ baseConfig = {
|
|||||||
'filesaver$': 'filesaver/FileSaver.js',
|
'filesaver$': 'filesaver/FileSaver.js',
|
||||||
'papaparse': 'papaparse/papaparse.min.js',
|
'papaparse': 'papaparse/papaparse.min.js',
|
||||||
'helpscout': 'helpscout.js',
|
'helpscout': 'helpscout.js',
|
||||||
'html2canvas': 'html2canvas/dist/html2canvas.js'
|
'html2canvas': 'html2canvas/dist/html2canvas.js',
|
||||||
|
'asyncqueue': 'asyncqueue/jquery.asyncqueue.js'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
node: {
|
node: {
|
||||||
|
Reference in New Issue
Block a user