- Resolves issues identified by @rafaehlers during testing

This commit is contained in:
Vlad
2016-01-07 22:47:59 -05:00
parent 5c7e11076d
commit 0c73c0fadc
11 changed files with 445 additions and 418 deletions

View File

@ -62,7 +62,7 @@ define(
if (_.contains(fieldsToExclude, selectedOptionId)) { if (_.contains(fieldsToExclude, selectedOptionId)) {
selectEvent.preventDefault(); selectEvent.preventDefault();
if (selectedOptionId === 'deselect') { if (selectedOptionId === 'deselect') {
jQuery(selectElement).select2('val', ''); jQuery(selectElement).val('').trigger('change');
} else { } else {
var allOptions = []; var allOptions = [];
_.each(container.find('option'), function (field) { _.each(container.find('option'), function (field) {
@ -70,7 +70,7 @@ define(
allOptions.push(field.value); allOptions.push(field.value);
} }
}); });
jQuery(selectElement).select2('val', allOptions); jQuery(selectElement).val(allOptions).trigger('change');
} }
jQuery(selectElement).select2('close'); jQuery(selectElement).select2('close');
} }
@ -138,11 +138,11 @@ define(
endpoint: 'ImportExport', endpoint: 'ImportExport',
action: 'processExport', action: 'processExport',
data: JSON.stringify({ data: JSON.stringify({
'exportConfirmedOption': exportData.exportConfirmedOption, 'export_confirmed_option': exportData.exportConfirmedOption,
'exportFormatOption': jQuery(':radio[name="option_format"]:checked').val(), 'export_format_option': jQuery(':radio[name="option_format"]:checked').val(),
'groupBySegmentOption': (groupBySegmentOptionElement.is(":visible")) ? groupBySegmentOptionElement.prop('checked') : false, 'group_by_segment_option': (groupBySegmentOptionElement.is(":visible")) ? groupBySegmentOptionElement.prop('checked') : false,
'segments': (exportData.segments) ? segmentsContainerElement.val() : false, 'segments': (exportData.segments) ? segmentsContainerElement.val() : false,
'subscriberFields': subscriberFieldsContainerElement.val() 'subscriber_fields': subscriberFieldsContainerElement.val()
}) })
}) })
.done(function (response) { .done(function (response) {

View File

@ -18,18 +18,6 @@ define(
return; return;
} }
jQuery(document).ready(function () { jQuery(document).ready(function () {
var data = [{ id: 0, text: 'enhancement' }, { id: 1, text: 'bug' }, { id: 'zz', text: 'duplicate' }, { id: 3, text: 'invalid' }, { id: 4, text: 'wontfix' }];
jQuery("#boo").select2({
data: data,
width: '20em'});
jQuery("#suka").click(function() {
jQuery("#boo").select2('val', ['zz']);
})
return;
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({
@ -133,7 +121,9 @@ define(
// get an approximate size of textarea paste in bytes // get an approximate size of textarea paste in bytes
var pasteSize = encodeURI(pasteInputElement.val()).split(/%..|./).length - 1; var pasteSize = encodeURI(pasteInputElement.val()).split(/%..|./).length - 1;
if (pasteSize > maxPostSizeBytes) { if (pasteSize > maxPostSizeBytes) {
MailPoet.Notice.error(MailPoetI18n.maxPostSizeNotice); MailPoet.Notice.error(MailPoetI18n.maxPostSizeNotice, {
timeout: 3000,
});
return; return;
} }
// delay loading indicator for 10ms or else it's just too fast :) // delay loading indicator for 10ms or else it's just too fast :)
@ -193,7 +183,9 @@ define(
}).done(function (response) { }).done(function (response) {
if (response.result === false) { if (response.result === false) {
MailPoet.Notice.hide(); MailPoet.Notice.hide();
MailPoet.Notice.error(response.error); MailPoet.Notice.error(response.error, {
timeout: 3000,
});
jQuery('.mailpoet_mailchimp-key-status') jQuery('.mailpoet_mailchimp-key-status')
.removeClass() .removeClass()
.addClass('mailpoet_mailchimp-key-status mailpoet_mailchimp-error'); .addClass('mailpoet_mailchimp-key-status mailpoet_mailchimp-error');
@ -216,7 +208,9 @@ define(
}).error(function (error) { }).error(function (error) {
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
MailPoet.Notice.error( MailPoet.Notice.error(
MailPoetI18n.serverError + error.statusText.toLowerCase() + '.' MailPoetI18n.serverError + error.statusText.toLowerCase() + '.', {
timeout: 3000,
}
); );
}); });
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
@ -241,13 +235,19 @@ define(
} }
else { else {
MailPoet.Notice.hide(); MailPoet.Notice.hide();
MailPoet.Notice.error(response.message); MailPoet.Notice
(response.message, {
timeout: 3000,
});
} }
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
}).error(function () { }).error(function () {
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
MailPoet.Notice.error( MailPoet.Notice.error(
MailPoetI18n.serverError + result.statusText.toLowerCase() + '.' MailPoetI18n.serverError + result.statusText.toLowerCase() + '.', {
timeout: 3000,
}
); );
}); });
}); });
@ -337,7 +337,9 @@ define(
comments: advancedOptionComments, comments: advancedOptionComments,
error: function () { error: function () {
MailPoet.Notice.hide(); MailPoet.Notice.hide();
MailPoet.Notice.error(MailPoetI18n.dataProcessingError); MailPoet.Notice.error(MailPoetI18n.dataProcessingError, {
timeout: 3000,
});
}, },
complete: function (CSV) { complete: function (CSV) {
for (var rowCount in CSV.data) { for (var rowCount in CSV.data) {
@ -416,7 +418,9 @@ define(
} }
else { else {
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
MailPoet.Notice.error(MailPoetI18n.noValidRecords); MailPoet.Notice.error(MailPoetI18n.noValidRecords, {
timeout: 3000,
});
} }
} }
} }
@ -546,6 +550,7 @@ define(
if (!segmentSelectionNotice.length) { if (!segmentSelectionNotice.length) {
MailPoet.Notice.error(MailPoetI18n.segmentSelectionRequired, { MailPoet.Notice.error(MailPoetI18n.segmentSelectionRequired, {
static: true, static: true,
timeout: 3000,
scroll: true, scroll: true,
id: 'segmentSelection', id: 'segmentSelection',
hideClose: true hideClose: true
@ -623,14 +628,18 @@ define(
else { else {
MailPoet.Modal.close(); MailPoet.Modal.close();
MailPoet.Notice.error( MailPoet.Notice.error(
MailPoetI18n.segmentCreateError + response.message + '.' MailPoetI18n.segmentCreateError + response.message + '.', {
timeout: 3000,
}
); );
} }
}) })
.error(function (error) { .error(function (error) {
MailPoet.Modal.close(); MailPoet.Modal.close();
MailPoet.Notice.error( MailPoet.Notice.error(
MailPoetI18n.serverError + error.statusText.toLowerCase() + '.' MailPoetI18n.serverError + error.statusText.toLowerCase() + '.', {
timeout: 3000
}
); );
}); });
} }
@ -831,18 +840,22 @@ define(
} }
}) })
}); });
jQuery(selectElement).data('column-id', new_column_data.id) jQuery(selectElement).data('column-id', new_column_data.id);
filterSubscribers(); filterSubscribers();
} }
else { else {
MailPoet.Notice.error(MailPoetI18n.customFieldCreateError); MailPoet.Notice.error(MailPoetI18n.customFieldCreateError, {
timeout: 3000,
});
} }
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
}) })
.error(function (error) { .error(function (error) {
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
MailPoet.Notice.error( MailPoet.Notice.error(
MailPoetI18n.serverError + error.statusText.toLowerCase() + '.' MailPoetI18n.serverError + error.statusText.toLowerCase() + '.', {
timeout: 3000,
}
); );
}); });
} }
@ -860,24 +873,23 @@ define(
elementId = jQuery(element).val(); elementId = jQuery(element).val();
// if another column has the same value and it's not an 'ignore', prompt user // if another column has the same value and it's not an 'ignore', prompt user
if (elementId === selectedOptionId if (elementId === selectedOptionId
&& element.id !== selectElement.id
&& elementId !== 'ignore') { && elementId !== 'ignore') {
if (confirm(MailPoetI18n.selectedValueAlreadyMatched + ' ' + MailPoetI18n.confirmCorrespondingColumn)) { if (confirm(MailPoetI18n.selectedValueAlreadyMatched + ' ' + MailPoetI18n.confirmCorrespondingColumn)) {
jQuery(element).data('column-id', 'ignore'); jQuery(element).data('column-id', 'ignore');
jQuery(selectElement).data('column-id', selectedOptionId);
filterSubscribers();
} }
else { else {
selectEvent.preventDefault(); selectEvent.preventDefault();
jQuery(selectElement).select2('close'); jQuery(selectElement).select2('close');
} }
} }
else if (element.id !== selectElement.id) {
jQuery(selectElement).data('column-id', selectedOptionId);
filterSubscribers();
}
}); });
} }
})
.on('select2:select', function (selectEvent) {
var selectElement = this,
selectedOptionId = selectEvent.params.data.id;
jQuery(selectElement).data('column-id', selectedOptionId);
filterSubscribers();
}); });
// filter subscribers' data to detect dates, emails, etc. // filter subscribers' data to detect dates, emails, etc.
@ -907,6 +919,7 @@ define(
if (!jQuery('[data-id="notice_invalidEmail"]').length) { if (!jQuery('[data-id="notice_invalidEmail"]').length) {
MailPoet.Notice.error(MailPoetI18n.columnContainsInvalidElement, { MailPoet.Notice.error(MailPoetI18n.columnContainsInvalidElement, {
static: true, static: true,
timeout: 3000,
scroll: true, scroll: true,
hideClose: true, hideClose: true,
id: 'invalidEmail' id: 'invalidEmail'
@ -986,6 +999,7 @@ define(
if (preventNextStep && !jQuery('.mailpoet_invalidDate').length) { if (preventNextStep && !jQuery('.mailpoet_invalidDate').length) {
MailPoet.Notice.error(MailPoetI18n.columnContainsInvalidDate, { MailPoet.Notice.error(MailPoetI18n.columnContainsInvalidDate, {
static: true, static: true,
timeout: 3000,
scroll: true, scroll: true,
hideClose: true, hideClose: true,
id: 'invalidDate' id: 'invalidDate'
@ -1057,7 +1071,9 @@ define(
}).done(function (response) { }).done(function (response) {
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
if (response.result === false) { if (response.result === false) {
MailPoet.Notice.error(response.error); MailPoet.Notice.error(response.error, {
timeout: 3000,
});
} else { } else {
mailpoetSegments = response.data.segments; mailpoetSegments = response.data.segments;
response.data.segments = _.map(segmentSelectElement.select2('data'), response.data.segments = _.map(segmentSelectElement.select2('data'),
@ -1071,7 +1087,9 @@ define(
}).error(function (error) { }).error(function (error) {
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
MailPoet.Notice.error( MailPoet.Notice.error(
MailPoetI18n.serverError + error.statusText.toLowerCase() + '.' MailPoetI18n.serverError + error.statusText.toLowerCase() + '.', {
timeout: 3000,
}
); );
}); });
}); });

View File

@ -34,7 +34,7 @@ class Env {
self::$file = $file; self::$file = $file;
self::$path = dirname(self::$file); self::$path = dirname(self::$file);
self::$plugin_name = 'mailpoet'; self::$plugin_name = 'mailpoet';
self::$plugin_url = plugin_dir_url(__FILE__); self::$plugin_url = plugin_dir_url(preg_replace('/lib/', '', __DIR__));
self::$views_path = self::$path . '/views'; self::$views_path = self::$path . '/views';
self::$assets_path = self::$path . '/assets'; self::$assets_path = self::$path . '/assets';
self::$assets_url = plugins_url('/assets', $file); self::$assets_url = plugins_url('/assets', $file);

View File

@ -154,7 +154,7 @@ class Subscriber extends Model {
$orm = $orm->selectExpr( $orm = $orm->selectExpr(
'CASE WHEN ' . 'CASE WHEN ' .
MP_CUSTOM_FIELDS_TABLE . '.id=' . $customField['id'] . ' THEN ' . MP_CUSTOM_FIELDS_TABLE . '.id=' . $customField['id'] . ' THEN ' .
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.value END as "' . $customField['name'].'"'); MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.value END as "' . $customField['id'].'"');
} }
$orm = $orm $orm = $orm
->leftOuterJoin( ->leftOuterJoin(

View File

@ -6,14 +6,16 @@ use MailPoet\Models\Segment;
use MailPoet\Util\Helpers; use MailPoet\Util\Helpers;
class BootStrapMenu { class BootStrapMenu {
public $action;
function __construct($action = null) { function __construct($action = null) {
$this->action = $action; $this->action = $action;
} }
function getSegments($withConfirmedSubscribers = false) { function getSegments($with_confirmed_subscribers = false) {
$segments = ($this->action === 'import') ? $segments = ($this->action === 'import') ?
Segment::getSegmentsWithSubscriberCount() : Segment::getSegmentsWithSubscriberCount() :
Segment::getSegmentsForExport($withConfirmedSubscribers); Segment::getSegmentsForExport($with_confirmed_subscribers);
return array_map(function ($segment) { return array_map(function ($segment) {
return array( return array(
'id' => $segment['id'], 'id' => $segment['id'],
@ -29,6 +31,7 @@ class BootStrapMenu {
'first_name' => __('First name'), 'first_name' => __('First name'),
'last_name' => __('Last name'), 'last_name' => __('Last name'),
'status' => __('Status') 'status' => __('Status')
// TODO: add additional fiels from MP2
/* /*
'confirmed_ip' => __('IP address') 'confirmed_ip' => __('IP address')
'confirmed_at' => __('Subscription date') 'confirmed_at' => __('Subscription date')
@ -36,22 +39,22 @@ class BootStrapMenu {
); );
} }
function formatSubscriberFields($subscriberFields) { function formatSubscriberFields($subscriber_fields) {
return array_map(function ($fieldId, $fieldName) { return array_map(function ($field_id, $field_name) {
return array( return array(
'id' => $fieldId, 'id' => $field_id,
'name' => $fieldName, 'name' => $field_name,
'type' => ($fieldId === 'confirmed_at') ? 'date' : null, 'type' => ($field_id === 'confirmed_at') ? 'date' : null,
'custom' => false 'custom' => false
); );
}, array_keys($subscriberFields), $subscriberFields); }, array_keys($subscriber_fields), $subscriber_fields);
} }
function getSubscriberCustomFields() { function getSubscriberCustomFields() {
return CustomField::findArray(); return CustomField::findArray();
} }
function formatSubscriberCustomFields($subscriberCustomFields) { function formatSubscriberCustomFields($subscriber_custom_fields) {
return array_map(function ($field) { return array_map(function ($field) {
return array( return array(
'id' => $field['id'], 'id' => $field['id'],
@ -59,12 +62,12 @@ class BootStrapMenu {
'type' => $field['type'], 'type' => $field['type'],
'custom' => true 'custom' => true
); );
}, $subscriberCustomFields); }, $subscriber_custom_fields);
} }
function formatFieldsForSelect2( function formatFieldsForSelect2(
$subscriberFields, $subscriber_fields,
$subscriberCustomFields) { $subscriber_custom_fields) {
$actions = ($this->action === 'import') ? $actions = ($this->action === 'import') ?
array( array(
array( array(
@ -93,14 +96,14 @@ class BootStrapMenu {
), ),
array( array(
'name' => __('System columns'), 'name' => __('System columns'),
'children' => $this->formatSubscriberFields($subscriberFields) 'children' => $this->formatSubscriberFields($subscriber_fields)
) )
); );
if($subscriberCustomFields) { if($subscriber_custom_fields) {
array_push($select2Fields, array( array_push($select2Fields, array(
'name' => __('User columns'), 'name' => __('User columns'),
'children' => $this->formatSubscriberCustomFields( 'children' => $this->formatSubscriberCustomFields(
$subscriberCustomFields $subscriber_custom_fields
) )
)); ));
} }
@ -108,28 +111,28 @@ class BootStrapMenu {
} }
function bootstrap() { function bootstrap() {
$subscriberFields = $this->getSubscriberFields(); $subscriber_fields = $this->getSubscriberFields();
$subscriberCustomFields = $this->getSubscriberCustomFields(); $subscriber_custom_fields = $this->getSubscriberCustomFields();
$data['segments'] = json_encode($this->getSegments()); $data['segments'] = json_encode($this->getSegments());
$data['subscriberFieldsSelect2'] = json_encode( $data['subscriberFieldsSelect2'] = json_encode(
$this->formatFieldsForSelect2( $this->formatFieldsForSelect2(
$subscriberFields, $subscriber_fields,
$subscriberCustomFields $subscriber_custom_fields
) )
); );
if($this->action === 'import') { if($this->action === 'import') {
$data['subscriberFields'] = json_encode( $data['subscriberFields'] = json_encode(
array_merge( array_merge(
$this->formatSubscriberFields($subscriberFields), $this->formatSubscriberFields($subscriber_fields),
$this->formatSubscriberCustomFields($subscriberCustomFields) $this->formatSubscriberCustomFields($subscriber_custom_fields)
) )
); );
$data['maxPostSizeBytes'] = Helpers::getMaxPostSize('bytes'); $data['maxPostSizeBytes'] = Helpers::getMaxPostSize('bytes');
$data['maxPostSize'] = Helpers::getMaxPostSize(); $data['maxPostSize'] = Helpers::getMaxPostSize();
} else { } else {
$data['segmentsWithConfirmedSubscribers'] = $data['segmentsWithConfirmedSubscribers'] =
json_encode($this->getSegments($withConfirmedSubscribers = true)); json_encode($this->getSegments($with_confirmed_subscribers = true));
} }
return $data; return $data;
} }
} }

View File

@ -11,106 +11,110 @@ use MailPoet\Util\Helpers;
use MailPoet\Util\XLSXWriter; use MailPoet\Util\XLSXWriter;
class Export { class Export {
public $export_confirmed_option;
public $export_format_option;
public $group_by_segment_option;
public $segments;
public $subscribers_without_segment;
public $subscriber_fields;
public $export_file;
public $export_file_URL;
public $profiler_start;
public function __construct($data) { public function __construct($data) {
$this->exportConfirmedOption = $data['exportConfirmedOption']; $this->export_confirmed_option = $data['export_confirmed_option'];
$this->exportFormatOption = $data['exportFormatOption']; $this->export_format_option = $data['export_format_option'];
$this->groupBySegmentOption = $data['groupBySegmentOption']; $this->group_by_segment_option = $data['group_by_segment_option'];
$this->segments = $data['segments']; $this->segments = $data['segments'];
$this->subscribersWithoutSegment = array_search(0, $this->segments); $this->subscribers_without_segment = array_search(0, $this->segments);
$this->subscriberFields = $data['subscriberFields']; $this->subscriber_fields = $data['subscriber_fields'];
$this->exportFile = $this->getExportFile($this->exportFormatOption); $this->export_file = $this->getExportFile($this->export_format_option);
$this->exportFileURL = $this->getExportFileURL($this->exportFile); $this->export_file_URL = $this->getExportFileURL($this->export_file);
$this->profilerStart = microtime(true); $this->profiler_start = microtime(true);
} }
function process() { function process() {
$subscribers = $this->getSubscribers(); $subscribers = $this->getSubscribers();
$subscriberCustomFields = $this->getSubscriberCustomFields(); $subscriber_custom_fields = $this->getSubscriberCustomFields();
$formattedSubscriberFields = $this->formatSubscriberFields( $formatted_subscriber_fields = $this->formatSubscriberFields(
$this->subscriberFields, $this->subscriber_fields,
$subscriberCustomFields $subscriber_custom_fields
); );
try { try {
if($this->exportFormatOption === 'csv') { if($this->export_format_option === 'csv') {
$CSVFile = fopen($this->exportFile, 'w'); $CSV_file = fopen($this->export_file, 'w');
$formatCSV = function ($row) { $format_CSV = function ($row) {
return '"' . str_replace('"', '\"', $row) . '"'; return '"' . str_replace('"', '\"', $row) . '"';
}; };
// add UTF-8 BOM (3 bytes, hex EF BB BF) at the start of the file for // add UTF-8 BOM (3 bytes, hex EF BB BF) at the start of the file for
// Excel to automatically recognize the encoding // Excel to automatically recognize the encoding
fwrite($CSVFile, chr(0xEF) . chr(0xBB) . chr(0xBF)); fwrite($CSV_file, chr(0xEF) . chr(0xBB) . chr(0xBF));
if($this->groupBySegmentOption) { if($this->group_by_segment_option) {
$formattedSubscriberFields[] = __('List'); $formatted_subscriber_fields[] = __('Segment');
} }
fwrite( fwrite(
$CSVFile, $CSV_file,
implode( implode(
',', ',',
array_map( array_map(
$formatCSV, $format_CSV,
$formattedSubscriberFields $formatted_subscriber_fields
) )
) . "\n" ) . "\n"
); );
foreach ($subscribers as $subscriber) { foreach($subscribers as $subscriber) {
$row = $this->formatSubscriberData( $row = $this->formatSubscriberData($subscriber);
$subscriber, if($this->group_by_segment_option) {
$formattedSubscriberFields
);
if($this->groupBySegmentOption) {
$row[] = ucwords($subscriber['segment_name']); $row[] = ucwords($subscriber['segment_name']);
} }
fwrite($CSVFile, implode(',', array_map($formatCSV, $row)) . "\n"); fwrite($CSV_file, implode(',', array_map($format_CSV, $row)) . "\n");
} }
fclose($CSVFile); fclose($CSV_file);
} else { } else {
$writer = new XLSXWriter(); $writer = new XLSXWriter();
$writer->setAuthor('MailPoet (www.mailpoet.com)'); $writer->setAuthor('MailPoet (www.mailpoet.com)');
$headerRow = array($formattedSubscriberFields); $header_row = array($formatted_subscriber_fields);
$lastSegment = false; $last_segment = false;
$rows = array(); $rows = array();
foreach ($subscribers as $subscriber) { foreach($subscribers as $subscriber) {
if($lastSegment && $lastSegment !== $subscriber['segment_name'] && if($last_segment && $last_segment !== $subscriber['segment_name'] &&
$this->groupBySegmentOption $this->group_by_segment_option
) { ) {
$writer->writeSheet( $writer->writeSheet(
array_merge($headerRow, $rows), ucwords($lastSegment) array_merge($header_row, $rows), ucwords($last_segment)
); );
$rows = array(); $rows = array();
} }
// detect RTL language and set Excel to properly display the sheet // detect RTL language and set Excel to properly display the sheet
$RTLRegex = '/\p{Arabic}|\p{Hebrew}/u'; $RTL_regex = '/\p{Arabic}|\p{Hebrew}/u';
if(!$writer->rtl && ( if(!$writer->rtl && (
preg_grep($RTLRegex, $subscriber) || preg_grep($RTL_regex, $subscriber) ||
preg_grep($RTLRegex, $formattedSubscriberFields)) preg_grep($RTL_regex, $formatted_subscriber_fields))
) { ) {
$writer->rtl = true; $writer->rtl = true;
} }
$rows[] = $this->formatSubscriberData( $rows[] = $this->formatSubscriberData($subscriber);
$subscriber, $last_segment = $subscriber['segment_name'];
$formattedSubscriberFields
);
$lastSegment = $subscriber['segment_name'];
} }
$writer->writeSheet( $writer->writeSheet(
array_merge($headerRow, $rows), array_merge($header_row, $rows),
($this->groupBySegmentOption) ? ($this->group_by_segment_option) ?
ucwords($subscriber['segment_name']) : ucwords($subscriber['segment_name']) :
'MailPoet' __('All Segments')
); );
$writer->writeToFile($this->exportFile); $writer->writeToFile($this->export_file);
} }
} catch (Exception $e) { } catch(Exception $e) {
return array( return array(
'result' => false, 'result' => false,
'error' => $e->getMessage() 'errors' => array($e->getMessage())
); );
} }
return array( return array(
'result' => true, 'result' => true,
'data' => array( 'data' => array(
'totalExported' => count($subscribers), 'totalExported' => count($subscribers),
'exportFileURL' => $this->exportFileURL 'exportFileURL' => $this->export_file_URL
), ),
'profiler' => $this->timeExecution() 'profiler' => $this->timeExecution()
); );
@ -134,11 +138,11 @@ class Export {
)) ))
->orderByAsc('segment_name') ->orderByAsc('segment_name')
->filter('filterWithCustomFieldsForExport'); ->filter('filterWithCustomFieldsForExport');
if($this->subscribersWithoutSegment !== false) { if($this->subscribers_without_segment !== false) {
$subscribers = $subscribers $subscribers = $subscribers
->selectExpr('CASE WHEN ' . Segment::$_table . '.name IS NOT NULL ' . ->selectExpr('CASE WHEN ' . Segment::$_table . '.name IS NOT NULL ' .
'THEN ' . Segment::$_table . '.name ' . 'THEN ' . Segment::$_table . '.name ' .
'ELSE "' . __('Not In List') . '" END as segment_name' 'ELSE "' . __('Not In Segment') . '" END as segment_name'
) )
->whereRaw( ->whereRaw(
SubscriberSegment::$_table . '.segment_id IN (' . SubscriberSegment::$_table . '.segment_id IN (' .
@ -151,11 +155,11 @@ class Export {
->select(Segment::$_table . '.name', 'segment_name') ->select(Segment::$_table . '.name', 'segment_name')
->whereIn(SubscriberSegment::$_table . '.segment_id', $this->segments); ->whereIn(SubscriberSegment::$_table . '.segment_id', $this->segments);
} }
if(!$this->groupBySegmentOption) { if(!$this->group_by_segment_option) {
$subscribers = $subscribers =
$subscribers->groupBy(Subscriber::$_table . '.id'); $subscribers->groupBy(Subscriber::$_table . '.id');
} }
if($this->exportConfirmedOption) { if($this->export_confirmed_option) {
$subscribers = $subscribers =
$subscribers->where(Subscriber::$_table . '.status', 'subscribed'); $subscribers->where(Subscriber::$_table . '.status', 'subscribed');
} }
@ -166,7 +170,7 @@ class Export {
function getExportFileURL($file) { function getExportFileURL($file) {
return sprintf( return sprintf(
'%s/%s/%s', '%s%s/%s',
Env::$plugin_url, Env::$plugin_url,
Env::$temp_name, Env::$temp_name,
basename($file) basename($file)
@ -189,32 +193,28 @@ class Export {
); );
} }
function formatSubscriberFields($subscriberFields, $subscriberCustomFields) { function formatSubscriberFields($subscriber_fields, $subscriber_custom_fields) {
$bootStrapMenu = new BootStrapMenu(); $bootstrap_menu = new BootStrapMenu();
$translatedFields = $bootStrapMenu->getSubscriberFields(); $translated_fields = $bootstrap_menu->getSubscriberFields();
return array_map(function ($field) use ( return array_map(function ($field) use (
$translatedFields, $subscriberCustomFields $translated_fields, $subscriber_custom_fields
) { ) {
$field = (isset($translatedFields[$field])) ? $field = (isset($translated_fields[$field])) ?
ucfirst($translatedFields[$field]) : ucfirst($translated_fields[$field]) :
ucfirst($field); ucfirst($field);
return (isset($subscriberCustomFields[$field])) ? return (isset($subscriber_custom_fields[$field])) ?
$subscriberCustomFields[$field] : $field; ucfirst($subscriber_custom_fields[$field]) : $field;
}, $subscriberFields); }, $subscriber_fields);
} }
function formatSubscriberData($subscriber, $subscriberCustomFields) { function formatSubscriberData($subscriber) {
return array_map(function ($field) use ( return array_map(function ($field) use ($subscriber) {
$subscriber, $subscriberCustomFields return $subscriber[$field];
) { }, $this->subscriber_fields);
return (isset($subscriberCustomFields[$field])) ?
$subscriberCustomFields[$field] :
$subscriber[$field];
}, $this->subscriberFields);
} }
function timeExecution() { function timeExecution() {
$profilerEnd = microtime(true); $profiler_end = microtime(true);
return ($profilerEnd - $this->profilerStart) / 60; return ($profiler_end - $this->profiler_start) / 60;
} }
} }

View File

@ -8,192 +8,201 @@ use MailPoet\Subscribers\ImportExport\BootStrapMenu;
use MailPoet\Util\Helpers; use MailPoet\Util\Helpers;
class Import { class Import {
public $subscribers_data;
public $segments;
public $update_subscribers;
public $subscriber_fields;
public $subscriber_custom_fields;
public $subscribers_count;
public $import_time;
public $profiler_start;
public function __construct($data) { public function __construct($data) {
$this->subscribersData = $data['subscribers']; $this->subscribers_data = $data['subscribers'];
$this->segments = $data['segments']; $this->segments = $data['segments'];
$this->updateSubscribers = $data['updateSubscribers']; $this->update_subscribers = $data['updateSubscribers'];
$this->subscriberFields = $this->getSubscriberFields( $this->subscriber_fields = $this->getSubscriberFields(
array_keys($this->subscribersData) array_keys($this->subscribers_data)
); );
$this->subscriberCustomFields = $this->getCustomSubscriberFields( $this->subscriber_custom_fields = $this->getCustomSubscriberFields(
array_keys($this->subscribersData) array_keys($this->subscribers_data)
); );
$this->subscribersCount = count(reset($this->subscribersData)); $this->subscribers_count = count(reset($this->subscribers_data));
$this->currentTime = date('Y-m-d H:i:s'); $this->import_time = date('Y-m-d H:i:s');
$this->profilerStart = microtime(true); $this->profiler_start = microtime(true);
} }
function process() { function process() {
$subscriberFields = $this->subscriberFields; $subscriber_fields = $this->subscriber_fields;
$subscriberCustomFields = $this->subscriberCustomFields; $subscriber_custom_fields = $this->subscriber_custom_fields;
$subscribersData = $this->subscribersData; $subscribers_data = $this->subscribers_data;
list ($subscribersData, $subscriberFields) = list ($subscribers_data, $subscriber_fields) =
$this->filterSubscriberStatus($subscribersData, $subscriberFields); $this->filterSubscriberStatus($subscribers_data, $subscriber_fields);
$this->deleteExistingTrashedSubscribers($subscribersData); $this->deleteExistingTrashedSubscribers($subscribers_data);
list($subscribersData, $subscriberFields) = $this->extendSubscribersAndFields( list($subscribers_data, $subscriber_fields) = $this->extendSubscribersAndFields(
$subscribersData, $subscriberFields $subscribers_data, $subscriber_fields
); );
list($existingSubscribers, $newSubscribers) = list($existing_subscribers, $new_subscribers) =
$this->filterExistingAndNewSubscribers($subscribersData); $this->filterExistingAndNewSubscribers($subscribers_data);
$createdSubscribers = $updatedSubscribers = array(); $created_subscribers = $updated_subscribers = array();
try { try {
if($newSubscribers) { if($new_subscribers) {
$createdSubscribers = $created_subscribers =
$this->createOrUpdateSubscribers( $this->createOrUpdateSubscribers(
'create', 'create',
$newSubscribers, $new_subscribers,
$subscriberFields, $subscriber_fields,
$subscriberCustomFields $subscriber_custom_fields
); );
} }
if($existingSubscribers && $this->updateSubscribers) { if($existing_subscribers && $this->update_subscribers) {
$updatedSubscribers = $updated_subscribers =
$this->createOrUpdateSubscribers( $this->createOrUpdateSubscribers(
'update', 'update',
$existingSubscribers, $existing_subscribers,
$subscriberFields, $subscriber_fields,
$subscriberCustomFields $subscriber_custom_fields
); );
if($createdSubscribers) { if($created_subscribers) {
// subtract added from updated subscribers when DB operation takes <1s // subtract added from updated subscribers when DB operation takes <1s
$updatedSubscribers = array_diff_key( $updated_subscribers = array_diff_key(
$updatedSubscribers, $updated_subscribers,
$createdSubscribers, $created_subscribers,
$subscriberCustomFields $subscriber_custom_fields
); );
} }
} }
} catch(\PDOException $e) { } catch(\PDOException $e) {
return array( return array(
'result' => false, 'result' => false,
'error' => $e->getMessage() 'errors' => array($e->getMessage())
); );
} }
$segments = new BootStrapMenu('import'); $segments = new BootStrapMenu('import');
return array( return array(
'result' => true, 'result' => true,
'data' => array( 'data' => array(
'created' => count($createdSubscribers), 'created' => count($created_subscribers),
'updated' => count($updatedSubscribers), 'updated' => count($updated_subscribers),
'segments' => $segments->getSegments() 'segments' => $segments->getSegments()
), ),
'profiler' => $this->timeExecution() 'profiler' => $this->timeExecution()
); );
} }
function filterExistingAndNewSubscribers($subscribersData) { function filterExistingAndNewSubscribers($subscribers_data) {
$existingRecords = array_filter( $existing_records = array_filter(
array_map(function ($subscriberEmails) { array_map(function ($subscriber_emails) {
return Subscriber::selectMany(array('email')) return Subscriber::selectMany(array('email'))
->whereIn('email', $subscriberEmails) ->whereIn('email', $subscriber_emails)
->whereNull('deleted_at') ->whereNull('deleted_at')
->findArray(); ->findArray();
}, array_chunk($subscribersData['email'], 200)) }, array_chunk($subscribers_data['email'], 200))
); );
if(!$existingRecords) { if(!$existing_records) {
return array( return array(
false, false,
$subscribersData $subscribers_data
); );
} }
$existingRecords = Helpers::flattenArray($existingRecords); $existing_records = Helpers::flattenArray($existing_records);
$newRecords = array_keys( $new_records = array_keys(
array_diff( array_diff(
$subscribersData['email'], $subscribers_data['email'],
$existingRecords $existing_records
) )
); );
if(!$newRecords) { if(!$new_records) {
return array( return array(
$subscribersData, $subscribers_data,
false false
); );
} }
$newSubscribers = $new_subscribers =
array_filter( array_filter(
array_map(function ($subscriber) use ($newRecords) { 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];
}, $newRecords); }, $new_records);
}, $subscribersData) }, $subscribers_data)
); );
$existingSubscribers = $existing_subscribers =
array_map(function ($subscriber) use ($newRecords) { 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 ($newRecords) { array_map(function ($index, $data) use ($new_records) {
if(!in_array($index, $newRecords)) return $data; if(!in_array($index, $new_records)) return $data;
}, array_keys($subscriber), $subscriber) }, array_keys($subscriber), $subscriber)
) )
); );
}, $subscribersData); }, $subscribers_data);
return array( return array(
$existingSubscribers, $existing_subscribers,
$newSubscribers $new_subscribers
); );
} }
function deleteExistingTrashedSubscribers($subscribersData) { function deleteExistingTrashedSubscribers($subscribers_data) {
$existingTrashedRecords = array_filter( $existing_trashed_records = array_filter(
array_map(function ($subscriberEmails) { array_map(function ($subscriber_emails) {
return Subscriber::selectMany(array('id')) return Subscriber::selectMany(array('id'))
->whereIn('email', $subscriberEmails) ->whereIn('email', $subscriber_emails)
->whereNotNull('deleted_at') ->whereNotNull('deleted_at')
->findArray(); ->findArray();
}, array_chunk($subscribersData['email'], 200)) }, array_chunk($subscribers_data['email'], 200))
); );
if(!$existingTrashedRecords) return; if(!$existing_trashed_records) return;
$existingTrashedRecords = Helpers::flattenArray($existingTrashedRecords); $existing_trashed_records = Helpers::flattenArray($existing_trashed_records);
foreach(array_chunk($existingTrashedRecords, 200) as $subscriberIds) { foreach(array_chunk($existing_trashed_records, 200) as $subscriber_ids) {
Subscriber::whereIn('id', $subscriberIds) Subscriber::whereIn('id', $subscriber_ids)
->deleteMany(); ->deleteMany();
SubscriberSegment::whereIn('subscriber_id', $subscriberIds) SubscriberSegment::whereIn('subscriber_id', $subscriber_ids)
->deleteMany(); ->deleteMany();
} }
} }
function extendSubscribersAndFields($subscribersData, $subscriberFields) { function extendSubscribersAndFields($subscribers_data, $subscriber_fields) {
$subscribersData['created_at'] = $this->filterSubscriberCreatedAtDate(); $subscribers_data['created_at'] = $this->filterSubscriberCreatedAtDate();
$subscriberFields[] = 'created_at'; $subscriber_fields[] = 'created_at';
return array( return array(
$subscribersData, $subscribers_data,
$subscriberFields $subscriber_fields
); );
} }
function getSubscriberFields($subscriberFields) { 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;
}, $subscriberFields) }, $subscriber_fields)
) )
); );
} }
function getCustomSubscriberFields($subscriberFields) { 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;
}, $subscriberFields) }, $subscriber_fields)
) )
); );
} }
function filterSubscriberCreatedAtDate() { function filterSubscriberCreatedAtDate() {
return array_fill(0, $this->subscribersCount, $this->currentTime); return array_fill(0, $this->subscribers_count, $this->import_time);
} }
function filterSubscriberStatus($subscribersData, $subscriberFields) { function filterSubscriberStatus($subscribers_data, $subscriber_fields) {
if(!in_array('status', $subscriberFields)) { if(!in_array('status', $subscriber_fields)) {
$subscribersData['status'] = $subscribers_data['status'] =
array_fill(0, count($subscribersData['email']), 'subscribed'); array_fill(0, count($subscribers_data['email']), 'subscribed');
$subscriberFields[] = 'status'; $subscriber_fields[] = 'status';
return array( return array(
$subscribersData, $subscribers_data,
$subscriberFields $subscriber_fields
); );
} }
$statuses = array( $statuses = array(
@ -216,7 +225,7 @@ class Import {
'false' 'false'
) )
); );
$subscribersData['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';
} }
@ -227,38 +236,38 @@ class Import {
return 'unconfirmed'; return 'unconfirmed';
} }
return 'subscribed'; // make "subscribed" a default status return 'subscribed'; // make "subscribed" a default status
}, $subscribersData['status']); }, $subscribers_data['status']);
return array( return array(
$subscribersData, $subscribers_data,
$subscriberFields $subscriber_fields
); );
} }
function createOrUpdateSubscribers( function createOrUpdateSubscribers(
$action, $action,
$subscribersData, $subscribers_data,
$subscriberFields, $subscriber_fields,
$subscriberCustomFields $subscriber_custom_fields
) { ) {
$subscribersCount = count(reset($subscribersData)) - 1; $subscribers_count = count(reset($subscribers_data)) - 1;
$subscribers = array_map(function ($index) use ($subscribersData, $subscriberFields) { $subscribers = array_map(function ($index) use ($subscribers_data, $subscriber_fields) {
return array_map(function ($field) use ($index, $subscribersData) { return array_map(function ($field) use ($index, $subscribers_data) {
return $subscribersData[$field][$index]; return $subscribers_data[$field][$index];
}, $subscriberFields); }, $subscriber_fields);
}, range(0, $subscribersCount)); }, range(0, $subscribers_count));
$currentTime = ($action === 'update') ? date('Y-m-d H:i:s') : $this->currentTime; $import_time = ($action === 'update') ? date('Y-m-d H:i:s') : $this->import_time;
foreach(array_chunk($subscribers, 100) as $data) { foreach(array_chunk($subscribers, 100) as $data) {
if($action == 'create') { if($action == 'create') {
Subscriber::createMultiple( Subscriber::createMultiple(
$subscriberFields, $subscriber_fields,
$data $data
); );
} }
if($action == 'update') { if($action == 'update') {
Subscriber::updateMultiple( Subscriber::updateMultiple(
$subscriberFields, $subscriber_fields,
$data, $data,
$currentTime $import_time
); );
} }
} }
@ -268,16 +277,16 @@ class Import {
'id', 'id',
'email' 'email'
)) ))
->where(($action === 'create') ? 'created_at' : 'updated_at', $currentTime) ->where(($action === 'create') ? 'created_at' : 'updated_at', $import_time)
->findArray(), ->findArray(),
'email', 'id' 'email', 'id'
); );
if($subscriberCustomFields) { if($subscriber_custom_fields) {
$this->createOrUpdateCustomFields( $this->createOrUpdateCustomFields(
($action === 'create') ? 'create' : 'update', ($action === 'create') ? 'create' : 'update',
$result, $result,
$subscribersData, $subscribers_data,
$subscriberCustomFields $subscriber_custom_fields
); );
} }
$this->addSubscribersToSegments( $this->addSubscribersToSegments(
@ -286,30 +295,30 @@ class Import {
); );
return $result; return $result;
} }
function createOrUpdateCustomFields( function createOrUpdateCustomFields(
$action, $action,
$dbSubscribers, $db_subscribers,
$subscribersData, $subscribers_data,
$subscriberCustomFields $subscriber_custom_fields
) { ) {
$subscribers = array_map( $subscribers = array_map(
function ($column) use ($dbSubscribers, $subscribersData) { function ($column) use ($db_subscribers, $subscribers_data) {
$count = range(0, count($subscribersData[$column]) - 1); $count = range(0, count($subscribers_data[$column]) - 1);
return array_map( return array_map(
function ($index, $value) function ($index, $value)
use ($dbSubscribers, $subscribersData, $column) { use ($db_subscribers, $subscribers_data, $column) {
$subscriberId = array_search( $subscriber_id = array_search(
$subscribersData['email'][$index], $subscribers_data['email'][$index],
$dbSubscribers $db_subscribers
); );
return array( return array(
$column, $column,
$subscriberId, $subscriber_id,
$value $value
); );
}, $count, $subscribersData[$column]); }, $count, $subscribers_data[$column]);
}, $subscriberCustomFields)[0]; }, $subscriber_custom_fields)[0];
foreach(array_chunk($subscribers, 200) as $data) { foreach(array_chunk($subscribers, 200) as $data) {
if($action === 'create') { if($action === 'create') {
SubscriberCustomField::createMultiple( SubscriberCustomField::createMultiple(
@ -323,15 +332,15 @@ class Import {
} }
} }
} }
function addSubscribersToSegments($subscribers, $segments) { function addSubscribersToSegments($subscribers, $segments) {
foreach(array_chunk($subscribers, 200) as $data) { foreach(array_chunk($subscribers, 200) as $data) {
SubscriberSegment::createMultiple($segments, $data); SubscriberSegment::createMultiple($segments, $data);
} }
} }
function timeExecution() { function timeExecution() {
$profilerEnd = microtime(true); $profiler_end = microtime(true);
return ($profilerEnd - $this->profilerStart) / 60; return ($profiler_end - $this->profiler_start) / 60;
} }
} }

View File

@ -10,15 +10,15 @@ use MailPoet\Subscribers\ImportExport\Export\Export;
class ExportCest { class ExportCest {
function _before() { function _before() {
$this->JSONdata = json_decode(file_get_contents(dirname(__FILE__) . '/ExportTestData.json'), true); $this->JSON_data = json_decode(file_get_contents(dirname(__FILE__) . '/ExportTestData.json'), true);
$this->subscriberFields = array( $this->subscriber_fields = array(
'first_name' => 'First name', 'first_name' => 'First name',
'last_name' => 'Last name', 'last_name' => 'Last name',
'email' => 'Email', 'email' => 'Email',
1 => 'Country' 1 => 'Country'
); );
$this->subscribersData = array( $this->subscribers_data = array(
array( array(
'first_name' => 'Adam', 'first_name' => 'Adam',
'last_name' => 'Smith', 'last_name' => 'Smith',
@ -42,13 +42,13 @@ class ExportCest {
'email' => 'paul@newman.com' 'email' => 'paul@newman.com'
) )
); );
$this->customFieldsData = array( $this->custom_fields_data = array(
array( array(
'name' => 'Country', 'name' => 'Country',
'type' => 'text' 'type' => 'text'
) )
); );
$this->segmentsData = array( $this->segments_data = array(
array( array(
'name' => 'Newspapers' 'name' => 'Newspapers'
), ),
@ -56,7 +56,7 @@ class ExportCest {
'name' => 'Journals' 'name' => 'Journals'
) )
); );
foreach ($this->subscribersData as $subscriber) { foreach($this->subscribers_data as $subscriber) {
if(isset($subscriber[1])) { if(isset($subscriber[1])) {
unset($subscriber[1]); unset($subscriber[1]);
} }
@ -64,20 +64,20 @@ class ExportCest {
$entity->hydrate($subscriber); $entity->hydrate($subscriber);
$entity->save(); $entity->save();
} }
foreach ($this->segmentsData as $customField) { foreach($this->segments_data as $custom_field) {
$entity = Segment::create(); $entity = Segment::create();
$entity->hydrate($customField); $entity->hydrate($custom_field);
$entity->save(); $entity->save();
} }
foreach ($this->customFieldsData as $customField) { foreach($this->custom_fields_data as $custom_field) {
$entity = CustomField::create(); $entity = CustomField::create();
$entity->hydrate($customField); $entity->hydrate($custom_field);
$entity->save(); $entity->save();
} }
$entity = SubscriberCustomField::create(); $entity = SubscriberCustomField::create();
$entity->subscriber_id = 2; $entity->subscriber_id = 2;
$entity->custom_field_id = 1; $entity->custom_field_id = 1;
$entity->value = $this->subscribersData[1][1]; $entity->value = $this->subscribers_data[1][1];
$entity->save(); $entity->save();
$entity = SubscriberSegment::create(); $entity = SubscriberSegment::create();
$entity->subscriber_id = 1; $entity->subscriber_id = 1;
@ -95,15 +95,15 @@ class ExportCest {
$entity->subscriber_id = 3; $entity->subscriber_id = 3;
$entity->segment_id = 2; $entity->segment_id = 2;
$entity->save(); $entity->save();
$this->export = new Export($this->JSONdata); $this->export = new Export($this->JSON_data);
} }
function itCanConstruct() { function itCanConstruct() {
expect($this->export->exportConfirmedOption) expect($this->export->export_confirmed_option)
->equals(false); ->equals(false);
expect($this->export->exportFormatOption) expect($this->export->export_format_option)
->equals('csv'); ->equals('csv');
expect($this->export->groupBySegmentOption) expect($this->export->group_by_segment_option)
->equals(false); ->equals(false);
expect($this->export->segments) expect($this->export->segments)
->equals( ->equals(
@ -112,9 +112,9 @@ class ExportCest {
2 2
) )
); );
expect($this->export->subscribersWithoutSegment) expect($this->export->subscribers_without_segment)
->equals(0); ->equals(0);
expect($this->export->subscriberFields) expect($this->export->subscriber_fields)
->equals( ->equals(
array( array(
'email', 'email',
@ -126,42 +126,42 @@ class ExportCest {
preg_match( preg_match(
'|' . '|' .
Env::$temp_path . '/MailPoet_export_[a-f0-9]{4}.' . Env::$temp_path . '/MailPoet_export_[a-f0-9]{4}.' .
$this->export->exportFormatOption . $this->export->export_format_option .
'|', $this->export->exportFile) '|', $this->export->export_file)
)->equals(1); )->equals(1);
expect( expect(
preg_match( preg_match(
'|' . '|' .
Env::$plugin_url . '/' . Env::$plugin_url .
Env::$temp_name . '/' . Env::$temp_name . '/' .
basename($this->export->exportFile) . basename($this->export->export_file) .
'|' '|'
, $this->export->exportFileURL) , $this->export->export_file_URL)
)->equals(1); )->equals(1);
} }
function itCanGetSubscriberCustomFields() { function itCanGetSubscriberCustomFields() {
$source = CustomField::where('name', $this->customFieldsData[0]['name']) $source = CustomField::where('name', $this->custom_fields_data[0]['name'])
->findOne(); ->findOne();
$target = $this->export->getSubscriberCustomFields(); $target = $this->export->getSubscriberCustomFields();
expect($target)->equals(array($source->id => $source->name)); expect($target)->equals(array($source->id => $source->name));
} }
function itCanFormatSubscriberFields() { function itCanFormatsubscriber_fields() {
$formattedSubscriberFields = $this->export->formatSubscriberFields( $formatted_subscriber_fields = $this->export->formatSubscriberFields(
array_keys($this->subscriberFields), array_keys($this->subscriber_fields),
$this->export->getSubscriberCustomFields() $this->export->getSubscriberCustomFields()
); );
expect($formattedSubscriberFields) expect($formatted_subscriber_fields)
->equals(array_values($this->subscriberFields)); ->equals(array_values($this->subscriber_fields));
} }
function itProperlyReturnsSubscriberCustomFields() { function itProperlyReturnsSubscriberCustomFields() {
$subscribers = $this->export->getSubscribers(); $subscribers = $this->export->getSubscribers();
foreach ($subscribers as $subscriber) { foreach($subscribers as $subscriber) {
if($subscriber['email'] === $this->subscribersData[1]) { if($subscriber['email'] === $this->subscribers_data[1]) {
expect($subscriber['Country']) expect($subscriber['Country'])
->equals($this->subscribersData[1][1]); ->equals($this->subscribers_data[1][1]);
} }
} }
} }
@ -182,26 +182,26 @@ class ExportCest {
} }
function itCanGroupSubscribersBySegments() { function itCanGroupSubscribersBySegments() {
$this->export->groupBySegmentOption = true; $this->export->group_by_segment_option = true;
$this->export->subscribersWithoutSegment = true; $this->export->subscribers_without_segment = true;
$subscribers = $this->export->getSubscribers(); $subscribers = $this->export->getSubscribers();
expect(count($subscribers))->equals(5); expect(count($subscribers))->equals(5);
} }
function itCanGetSubscribersOnlyWithoutSegments() { function itCanGetSubscribersOnlyWithoutSegments() {
$this->export->segments = array(0); $this->export->segments = array(0);
$this->export->subscribersWithoutSegment = true; $this->export->subscribers_without_segment = true;
$subscribers = $this->export->getSubscribers(); $subscribers = $this->export->getSubscribers();
expect(count($subscribers))->equals(1); expect(count($subscribers))->equals(1);
expect($subscribers[0]['segment_name'])->equals('Not In List'); expect($subscribers[0]['segment_name'])->equals('Not In Segment');
} }
function itCanGetOnlyConfirmedSubscribers() { function itCanGetOnlyConfirmedSubscribers() {
$this->export->exportConfirmedOption = true; $this->export->export_confirmed_option = true;
$subscribers = $this->export->getSubscribers(); $subscribers = $this->export->getSubscribers();
expect(count($subscribers))->equals(1); expect(count($subscribers))->equals(1);
expect($subscribers[0]['email']) expect($subscribers[0]['email'])
->equals($this->subscribersData[1]['email']); ->equals($this->subscribers_data[1]['email']);
} }
function itCanGetSubscribersOnlyInSegments() { function itCanGetSubscribersOnlyInSegments() {
@ -213,18 +213,17 @@ class ExportCest {
} }
function itCanProcess() { function itCanProcess() {
$this->export->exportFile = $this->export->getExportFile('csv'); $this->export->export_file = $this->export->getExportFile('csv');
$this->export->exportFormatOption = 'csv'; $this->export->export_format_option = 'csv';
$this->export->process(); $this->export->process();
$CSVFileSize = filesize($this->export->exportFile); $CSV_file_size = filesize($this->export->export_file);
$this->export->exportFile = $this->export->getExportFile('xls'); $this->export->export_file = $this->export->getExportFile('xls');
$this->export->exportFormatOption = 'xls'; $this->export->export_format_option = 'xls';
$this->export->process(); $this->export->process();
$XLSFileSize = filesize($this->export->exportFile); $XLS_file_size = filesize($this->export->export_file);
expect($CSVFileSize)->greaterThan(0); expect($CSV_file_size)->greaterThan(0);
expect($XLSFileSize)->greaterThan(0); expect($XLS_file_size)->greaterThan(0);
expect($XLSFileSize)->greaterThan($CSVFileSize); expect($XLS_file_size)->greaterThan($CSV_file_size);
} }
function _after() { function _after() {

View File

@ -1,12 +1,12 @@
{ {
"exportConfirmedOption": false, "export_confirmed_option": false,
"exportFormatOption": "csv", "export_format_option": "csv",
"groupBySegmentOption": false, "group_by_segment_option": false,
"segments": [ "segments": [
"1", "1",
"2" "2"
], ],
"subscriberFields": [ "subscriber_fields": [
"email", "email",
"first_name", "first_name",
"1" "1"

View File

@ -8,8 +8,8 @@ use MailPoet\Util\Helpers;
class ImportCest { class ImportCest {
function __construct() { function __construct() {
$this->JSONdata = json_decode(file_get_contents(dirname(__FILE__) . '/ImportTestData.json'), true); $this->JSON_data = json_decode(file_get_contents(dirname(__FILE__) . '/ImportTestData.json'), true);
$this->subscribersData = array( $this->subscribers_data = array(
'first_name' => array( 'first_name' => array(
'Adam', 'Adam',
'Mary' 'Mary'
@ -27,28 +27,28 @@ class ImportCest {
'Brazil' 'Brazil'
) )
); );
$this->subscriberFields = array( $this->subscriber_fields = array(
'first_name', 'first_name',
'last_name', 'last_name',
'email' 'email'
); );
$this->segments = range(0, 1); $this->segments = range(0, 1);
$this->subscriberCustomFields = array(777); $this->subscriber_custom_fields = array(777);
$this->import = new Import($this->JSONdata); $this->import = new Import($this->JSON_data);
} }
function itCanConstruct() { function itCanConstruct() {
expect($this->import->subscribersData)->equals($this->JSONdata['subscribers']); expect($this->import->subscribers_data)->equals($this->JSON_data['subscribers']);
expect($this->import->segments)->equals($this->JSONdata['segments']); expect($this->import->segments)->equals($this->JSON_data['segments']);
expect(is_array($this->import->subscriberFields))->true(); expect(is_array($this->import->subscriber_fields))->true();
expect(is_array($this->import->subscriberCustomFields))->true(); expect(is_array($this->import->subscriber_custom_fields))->true();
expect($this->import->subscribersCount)->equals( expect($this->import->subscribers_count)->equals(
count($this->JSONdata['subscribers']['email']) count($this->JSON_data['subscribers']['email'])
); );
expect( expect(
preg_match( preg_match(
'/\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}/', '/\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}/',
$this->import->currentTime) $this->import->import_time)
)->equals(1); )->equals(1);
} }
@ -62,23 +62,23 @@ class ImportCest {
)); ));
$subscriber->save(); $subscriber->save();
list($existing, $new) = $this->import->filterExistingAndNewSubscribers( list($existing, $new) = $this->import->filterExistingAndNewSubscribers(
$this->subscribersData $this->subscribers_data
); );
expect($existing['email'][0])->equals($this->subscribersData['email'][0]); expect($existing['email'][0])->equals($this->subscribers_data['email'][0]);
expect($new['email'][0])->equals($this->subscribersData['email'][1]); expect($new['email'][0])->equals($this->subscribers_data['email'][1]);
} }
function itCanExtendSubscribersAndFields() { function itCanExtendSubscribersAndFields() {
expect(in_array('created_at', $this->import->subscriberFields))->false(); expect(in_array('created_at', $this->import->subscriber_fields))->false();
expect(isset($this->import->subscriberFields['created_at']))->false(); expect(isset($this->import->subscriber_fields['created_at']))->false();
list($subscribers, $fields) = $this->import->extendSubscribersAndFields( list($subscribers, $fields) = $this->import->extendSubscribersAndFields(
$this->import->subscribersData, $this->import->subscribers_data,
$this->import->subscriberFields $this->import->subscriber_fields
); );
expect(in_array('created_at', $fields))->true(); expect(in_array('created_at', $fields))->true();
expect(isset($this->import->subscriberFields['created_at']))->false(); expect(isset($this->import->subscriber_fields['created_at']))->false();
expect(count($subscribers['created_at'])) expect(count($subscribers['created_at']))
->equals($this->import->subscribersCount); ->equals($this->import->subscribers_count);
} }
function itCanGetSubscriberFields() { function itCanGetSubscriberFields() {
@ -106,17 +106,17 @@ class ImportCest {
} }
function itCanFilterSubscriberStatus() { function itCanFilterSubscriberStatus() {
$subscibersData = $this->subscribersData; $subscibers_data = $this->subscribers_data;
$subscriberFields = $this->subscriberFields; $subscriber_fields = $this->subscriber_fields;
list($subscibersData, $subsciberFields) = list($subscibers_data, $subsciber_fields) =
$this->import->filterSubscriberStatus($subscibersData, $subscriberFields); $this->import->filterSubscriberStatus($subscibers_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($subsciberFields))->equals('status'); expect(array_pop($subsciber_fields))->equals('status');
expect($subscibersData['status'][0])->equals('subscribed'); expect($subscibers_data['status'][0])->equals('subscribed');
expect(count($subscibersData['status']))->equals(2); expect(count($subscibers_data['status']))->equals(2);
$subscriberFields[] = 'status'; $subscriber_fields[] = 'status';
$subscibersData = array( $subscibers_data = array(
'status' => array( 'status' => array(
#subscribed #subscribed
'subscribed', 'subscribed',
@ -135,9 +135,9 @@ class ImportCest {
'false' 'false'
), ),
); );
list($subscibersData, $subsciberFields) = list($subscibers_data, $subsciber_fields) =
$this->import->filterSubscriberStatus($subscibersData, $subscriberFields); $this->import->filterSubscriberStatus($subscibers_data, $subscriber_fields);
expect($subscibersData)->equals( expect($subscibers_data)->equals(
array( array(
'status' => array( 'status' => array(
'subscribed', 'subscribed',
@ -158,73 +158,73 @@ class ImportCest {
} }
function itCanAddOrUpdateSubscribers() { function itCanAddOrUpdateSubscribers() {
$subscribersData = $this->subscribersData; $subscribers_data = $this->subscribers_data;
$this->import->createOrUpdateSubscribers( $this->import->createOrUpdateSubscribers(
'create', 'create',
$subscribersData, $subscribers_data,
$this->subscriberFields, $this->subscriber_fields,
false false
); );
$subscribers = Subscriber::findArray(); $subscribers = Subscriber::findArray();
expect(count($subscribers))->equals(2); expect(count($subscribers))->equals(2);
expect($subscribers[0]['email']) expect($subscribers[0]['email'])
->equals($subscribersData['email'][0]); ->equals($subscribers_data['email'][0]);
$data['first_name'][1] = 'MaryJane'; $data['first_name'][1] = 'MaryJane';
$this->import->createOrUpdateSubscribers( $this->import->createOrUpdateSubscribers(
'update', 'update',
$subscribersData, $subscribers_data,
$this->subscriberFields, $this->subscriber_fields,
false false
); );
$subscribers = Subscriber::findArray(); $subscribers = Subscriber::findArray();
expect($subscribers[1]['first_name']) expect($subscribers[1]['first_name'])
->equals($subscribersData['first_name'][1]); ->equals($subscribers_data['first_name'][1]);
} }
function itCanDeleteTrashedSubscribers() { function itCanDeleteTrashedSubscribers() {
$subscribersData = $this->subscribersData; $subscribers_data = $this->subscribers_data;
$subscriberFields = $this->subscriberFields; $subscriber_fields = $this->subscriber_fields;
$subscribersData['deleted_at'] = array( $subscribers_data['deleted_at'] = array(
null, null,
date('Y-m-d H:i:s') date('Y-m-d H:i:s')
); );
$subscriberFields[] = 'deleted_at'; $subscriber_fields[] = 'deleted_at';
$this->import->createOrUpdateSubscribers( $this->import->createOrUpdateSubscribers(
'create', 'create',
$subscribersData, $subscribers_data,
$subscriberFields, $subscriber_fields,
false false
); );
$dbSubscribers = Helpers::arrayColumn( $db_subscribers = Helpers::arrayColumn(
Subscriber::select('id') Subscriber::select('id')
->findArray(), ->findArray(),
'id' 'id'
); );
expect(count($dbSubscribers))->equals(2); expect(count($db_subscribers))->equals(2);
$this->import->addSubscribersToSegments( $this->import->addSubscribersToSegments(
$dbSubscribers, $db_subscribers,
$this->segments $this->segments
); );
$subscribersSegments = SubscriberSegment::findArray(); $subscribers_segments = SubscriberSegment::findArray();
expect(count($subscribersSegments))->equals(4); expect(count($subscribers_segments))->equals(4);
$this->import->deleteExistingTrashedSubscribers( $this->import->deleteExistingTrashedSubscribers(
$subscribersData $subscribers_data
); );
$subscribersSegments = SubscriberSegment::findArray(); $subscribers_segments = SubscriberSegment::findArray();
$dbSubscribers = Subscriber::findArray(); $db_subscribers = Subscriber::findArray();
expect(count($subscribersSegments))->equals(2); expect(count($subscribers_segments))->equals(2);
expect(count($dbSubscribers))->equals(1); expect(count($db_subscribers))->equals(1);
} }
function itCanCreateOrUpdateCustomFields() { function itCanCreateOrUpdateCustomFields() {
$subscribersData = $this->subscribersData; $subscribers_data = $this->subscribers_data;
$this->import->createOrUpdateSubscribers( $this->import->createOrUpdateSubscribers(
'create', 'create',
$subscribersData, $subscribers_data,
$this->subscriberFields, $this->subscriber_fields,
false false
); );
$dbSubscribers = Helpers::arrayColumn( $db_subscribers = Helpers::arrayColumn(
Subscriber::selectMany( Subscriber::selectMany(
array( array(
'id', 'id',
@ -235,60 +235,60 @@ class ImportCest {
); );
$this->import->createOrUpdateCustomFields( $this->import->createOrUpdateCustomFields(
'create', 'create',
$dbSubscribers, $db_subscribers,
$subscribersData, $subscribers_data,
$this->subscriberCustomFields $this->subscriber_custom_fields
); );
$subscriberCustomFields = SubscriberCustomField::findArray(); $subscriber_custom_fields = SubscriberCustomField::findArray();
expect(count($subscriberCustomFields))->equals(2); expect(count($subscriber_custom_fields))->equals(2);
expect($subscriberCustomFields[0]['value']) expect($subscriber_custom_fields[0]['value'])
->equals($subscribersData[777][0]); ->equals($subscribers_data[777][0]);
$subscribersData[777][1] = 'Rio'; $subscribers_data[777][1] = 'Rio';
$this->import->createOrUpdateCustomFields( $this->import->createOrUpdateCustomFields(
'update', 'update',
$dbSubscribers, $db_subscribers,
$subscribersData, $subscribers_data,
$this->subscriberCustomFields $this->subscriber_custom_fields
); );
$subscriberCustomFields = SubscriberCustomField::findArray(); $subscriber_custom_fields = SubscriberCustomField::findArray();
expect($subscriberCustomFields[1]['value']) expect($subscriber_custom_fields[1]['value'])
->equals($subscribersData[777][1]); ->equals($subscribers_data[777][1]);
} }
function itCanaddSubscribersToSegments() { function itCanaddSubscribersToSegments() {
$subscribersData = $this->subscribersData; $subscribers_data = $this->subscribers_data;
$this->import->createOrUpdateSubscribers( $this->import->createOrUpdateSubscribers(
'create', 'create',
$subscribersData, $subscribers_data,
$this->subscriberFields, $this->subscriber_fields,
false false
); );
$dbSubscribers = Helpers::arrayColumn( $db_subscribers = Helpers::arrayColumn(
Subscriber::select('id') Subscriber::select('id')
->findArray(), ->findArray(),
'id' 'id'
); );
$this->import->addSubscribersToSegments( $this->import->addSubscribersToSegments(
$dbSubscribers, $db_subscribers,
$this->segments $this->segments
); );
$subscribersSegments = SubscriberSegment::findArray(); $subscribers_segments = SubscriberSegment::findArray();
// 2 subscribers * 2 segments // 2 subscribers * 2 segments
expect(count($subscribersSegments))->equals(4); expect(count($subscribers_segments))->equals(4);
} }
function itCanDeleteExistingTrashedSubscribers() { function itCanDeleteExistingTrashedSubscribers() {
$subscribersData = $this->subscribersData; $subscribers_data = $this->subscribers_data;
$subscriberFields = $this->subscriberFields; $subscriber_fields = $this->subscriber_fields;
$subscriberFields[] = 'deleted_at'; $subscriber_fields[] = 'deleted_at';
$subscribersData['deleted_at'] = array( $subscribers_data['deleted_at'] = array(
null, null,
date('Y-m-d H:i:s') date('Y-m-d H:i:s')
); );
$this->import->createOrUpdateSubscribers( $this->import->createOrUpdateSubscribers(
'create', 'create',
$subscribersData, $subscribers_data,
$subscriberFields, $subscriber_fields,
false false
); );
} }
@ -304,11 +304,12 @@ class ImportCest {
Subscriber::where('email', 'mbanks4@blinklist.com') Subscriber::where('email', 'mbanks4@blinklist.com')
->findOne() ->findOne()
->delete(); ->delete();
$import->currentTime = date('Y-m-d 12:i:s'); // 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(996);
$import->updateSubscribers = false; $import->update_subscribers = false;
$result = $import->process(); $result = $import->process();
expect($result['data']['created'])->equals(0); expect($result['data']['created'])->equals(0);
expect($result['data']['updated'])->equals(0); expect($result['data']['updated'])->equals(0);

View File

@ -5,9 +5,6 @@
<%= __('Import') %> <%= __('Import') %>
<a class="add-new-h2" href="?page=mailpoet-subscribers#/"><%= __('Back to list') %></a> <a class="add-new-h2" href="?page=mailpoet-subscribers#/"><%= __('Back to list') %></a>
</h2> </h2>
<select class="test" id="boo"></select>
<a href="#" id="suka">asdasdasd</a>;
<!-- STEP 1: method selection --> <!-- STEP 1: method selection -->
<% include 'subscribers/importExport/import/step1.html' %> <% include 'subscribers/importExport/import/step1.html' %>
<!-- STEP 2: subscriber data manipulation --> <!-- STEP 2: subscriber data manipulation -->