- Update import to autodetect dates (UI) and convert them to datetime
format (backend) - Fixes unit test - Fixes code formatting in Date class
This commit is contained in:
@@ -51,6 +51,12 @@ define(
|
|||||||
* STEP 1 (upload or copy/paste)
|
* STEP 1 (upload or copy/paste)
|
||||||
*/
|
*/
|
||||||
router.on('route:step1', function () {
|
router.on('route:step1', function () {
|
||||||
|
// set or reset temporary validation rule on all columns
|
||||||
|
mailpoetColumns = jQuery.map(mailpoetColumns, function (column, columnIndex) {
|
||||||
|
column.validation_rule = false;
|
||||||
|
return column;
|
||||||
|
});
|
||||||
|
|
||||||
if (typeof (importData.step1) !== 'undefined') {
|
if (typeof (importData.step1) !== 'undefined') {
|
||||||
showCurrentStep();
|
showCurrentStep();
|
||||||
return;
|
return;
|
||||||
@@ -797,6 +803,7 @@ define(
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
jQuery(selectElement).data('column-id', new_column_data.id);
|
jQuery(selectElement).data('column-id', new_column_data.id);
|
||||||
|
jQuery(selectElement).data('validation-rule', false);
|
||||||
filterSubscribers();
|
filterSubscribers();
|
||||||
// close popup
|
// close popup
|
||||||
MailPoet.Modal.close();
|
MailPoet.Modal.close();
|
||||||
@@ -847,22 +854,22 @@ define(
|
|||||||
.remove();
|
.remove();
|
||||||
var subscribersClone = jQuery.extend(true, {}, subscribers),
|
var subscribersClone = jQuery.extend(true, {}, subscribers),
|
||||||
preventNextStep = false,
|
preventNextStep = false,
|
||||||
displayedColumnsIds = jQuery.map(
|
displayedColumns = jQuery.map(
|
||||||
jQuery('.mailpoet_subscribers_column_data_match'), function (data) {
|
jQuery('.mailpoet_subscribers_column_data_match'), function (element, elementIndex) {
|
||||||
var columnId = jQuery(data).data('column-id');
|
var columnId = jQuery(element).data('column-id');
|
||||||
jQuery(data).val(columnId).trigger('change');
|
var validationRule = jQuery(element).data('validation-rule');
|
||||||
return columnId;
|
jQuery(element).val(columnId).trigger('change');
|
||||||
|
return { id: columnId, index: elementIndex, validationRule: validationRule, element: element };
|
||||||
});
|
});
|
||||||
// iterate through the object of mailpoet columns
|
// iterate through the object of mailpoet columns
|
||||||
jQuery.map(mailpoetColumns, function (column) {
|
jQuery.map(mailpoetColumns, function (column, columnIndex) {
|
||||||
// check if the column id matches the selected id of one of the
|
// check if the column id matches the selected id of one of the
|
||||||
// subscriber's data columns
|
// subscriber's data columns
|
||||||
var matchedColumn = jQuery.inArray(column.id, displayedColumnsIds);
|
var matchedColumn = _.find(displayedColumns, function(data) { return data.id === column.id; });
|
||||||
|
// EMAIL filter: if the first value in the column doesn't have a valid
|
||||||
// EMAIL filter: if the last value in the column doesn't have a valid
|
|
||||||
// email, hide the next button
|
// email, hide the next button
|
||||||
if (column.id === "email") {
|
if (column.id === 'email') {
|
||||||
if (!emailRegex.test(subscribersClone.subscribers[0][matchedColumn])) {
|
if (!emailRegex.test(subscribersClone.subscribers[0][matchedColumn.index])) {
|
||||||
preventNextStep = true;
|
preventNextStep = true;
|
||||||
if (!jQuery('[data-id="notice_invalidEmail"]').length) {
|
if (!jQuery('[data-id="notice_invalidEmail"]').length) {
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidElement'), {
|
MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidElement'), {
|
||||||
@@ -878,39 +885,63 @@ define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// DATE filter: if column type is date, check if we can recognize it
|
// DATE filter: if column type is date, check if we can recognize it
|
||||||
if (column.type === 'date' && matchedColumn !== -1) {
|
if (column.type === 'date' && matchedColumn) {
|
||||||
jQuery.map(subscribersClone.subscribers, function (data, position) {
|
var allowedDateFormats = [
|
||||||
var rowData = data[matchedColumn];
|
Moment.ISO_8601,
|
||||||
var dateFormat = column.params.date_format.toUpperCase();
|
'YYYY/MM/DD',
|
||||||
var date = Moment(rowData, dateFormat, true);
|
'MM/DD/YYYY',
|
||||||
if (position !== fillerPosition) {
|
'DD/MM/YYYY',
|
||||||
// check if date exists
|
'YYYY/MM/DD',
|
||||||
if (rowData.trim() === '') {
|
'YYYY/DD/MM',
|
||||||
data[matchedColumn] =
|
'MM/YYYY',
|
||||||
'<span class="mailpoet_data_match mailpoet_import_error" title="'
|
'YYYY/MM',
|
||||||
+ MailPoet.I18n.t('noDateFieldMatch') + '">'
|
'YYYY'
|
||||||
+ MailPoet.I18n.t('emptyDate')
|
];
|
||||||
+ '</span>';
|
var firstRowData = subscribersClone.subscribers[0][matchedColumn.index];
|
||||||
preventNextStep = true;
|
var validationRule = false;
|
||||||
return;
|
// check if date exists
|
||||||
}
|
if (firstRowData.trim() === '') {
|
||||||
// check if date is valid
|
subscribersClone.subscribers[0][matchedColumn.index] =
|
||||||
if (date.isValid()) {
|
'<span class="mailpoet_data_match mailpoet_import_error" title="'
|
||||||
data[matchedColumn] +=
|
+ MailPoet.I18n.t('noDateFieldMatch') + '">'
|
||||||
'<span class="mailpoet_data_match" title="'
|
+ MailPoet.I18n.t('emptyDate')
|
||||||
+ MailPoet.I18n.t('verifyDateMatch') + '">'
|
+ '</span>';
|
||||||
+ MailPoet.Date.format(date)
|
preventNextStep = true;
|
||||||
+ '</span>';
|
}
|
||||||
}
|
else {
|
||||||
else {
|
for (var format in allowedDateFormats) {
|
||||||
data[matchedColumn] +=
|
var testedFormat = allowedDateFormats[format]
|
||||||
'<span class="mailpoet_data_match mailpoet_import_error" title="'
|
if (Moment(firstRowData, testedFormat, true).isValid()) {
|
||||||
+ MailPoet.I18n.t('noDateFieldMatch') + '">'
|
var validationRule = (typeof(testedFormat) === 'function') ?
|
||||||
+ MailPoet.I18n.t('dateMatchError') + ' (' + dateFormat + ') '
|
'datetime' :
|
||||||
+ '</span>';
|
testedFormat
|
||||||
preventNextStep = true;
|
// set validation on the column element
|
||||||
|
jQuery(matchedColumn.element).data('validation-rule', validationRule);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (validationRule === 'datetime') validationRule = Moment.ISO_8601;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
jQuery.map(subscribersClone.subscribers, function (data, index) {
|
||||||
|
if (index === fillerPosition) return;
|
||||||
|
var rowData = data[matchedColumn.index];
|
||||||
|
var date = Moment(rowData, testedFormat, true);
|
||||||
|
// validate date:
|
||||||
|
if (date.isValid()) {
|
||||||
|
data[matchedColumn.index] +=
|
||||||
|
'<span class="mailpoet_data_match" title="'
|
||||||
|
+ MailPoet.I18n.t('verifyDateMatch') + '">'
|
||||||
|
+ MailPoet.Date.format(date)
|
||||||
|
+ '</span>';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data[matchedColumn.index] +=
|
||||||
|
'<span class="mailpoet_data_match mailpoet_import_error" title="'
|
||||||
|
+ MailPoet.I18n.t('noDateFieldMatch') + '">'
|
||||||
|
+ MailPoet.I18n.t('dateMatchError')
|
||||||
|
+ '</span>';
|
||||||
|
preventNextStep = true;
|
||||||
|
};
|
||||||
});
|
});
|
||||||
if (preventNextStep && !jQuery('.mailpoet_invalidDate').length) {
|
if (preventNextStep && !jQuery('.mailpoet_invalidDate').length) {
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidDate'), {
|
MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidDate'), {
|
||||||
@@ -980,10 +1011,11 @@ define(
|
|||||||
_.each(jQuery('select.mailpoet_subscribers_column_data_match'),
|
_.each(jQuery('select.mailpoet_subscribers_column_data_match'),
|
||||||
function (column, columnIndex) {
|
function (column, columnIndex) {
|
||||||
var columnId = jQuery(column).data('column-id');
|
var columnId = jQuery(column).data('column-id');
|
||||||
|
var validationRule = jQuery(column).data('validation-rule');
|
||||||
if (columnId === 'ignore') {
|
if (columnId === 'ignore') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
columns[columnId] = columnIndex;
|
columns[columnId] = { index: columnIndex, validation_rule: validationRule };
|
||||||
});
|
});
|
||||||
|
|
||||||
_.each(subscribers, function () {
|
_.each(subscribers, function () {
|
||||||
|
@@ -197,16 +197,15 @@ class Date extends Base {
|
|||||||
|
|
||||||
static function convertDateToDatetime($date, $date_format) {
|
static function convertDateToDatetime($date, $date_format) {
|
||||||
$datetime = false;
|
$datetime = false;
|
||||||
if ($date_format === 'datetime') {
|
if($date_format === 'datetime') {
|
||||||
$datetime = $date;
|
$datetime = $date;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$parsed_date = explode('/', $date);
|
$parsed_date = explode('/', $date);
|
||||||
$parsed_date_format = explode('/', $date_format);
|
$parsed_date_format = explode('/', $date_format);
|
||||||
$year_position = array_search('YYYY', $parsed_date_format);
|
$year_position = array_search('YYYY', $parsed_date_format);
|
||||||
$month_position = array_search('MM', $parsed_date_format);
|
$month_position = array_search('MM', $parsed_date_format);
|
||||||
$day_position = array_search('DD', $parsed_date_format);
|
$day_position = array_search('DD', $parsed_date_format);
|
||||||
if(count($parsed_date) === 3) {
|
if(count($parsed_date) === 3) {
|
||||||
// create date from any combination of mm, dd and yyyy
|
// create date from any combination of mm, dd and yyyy
|
||||||
$parsed_date = array(
|
$parsed_date = array(
|
||||||
'year' => $parsed_date[$year_position],
|
'year' => $parsed_date[$year_position],
|
||||||
|
@@ -169,7 +169,8 @@ class SubscriberTest extends MailPoetTest {
|
|||||||
'name' => 'Birthday',
|
'name' => 'Birthday',
|
||||||
'type' => 'date',
|
'type' => 'date',
|
||||||
'params' => array(
|
'params' => array(
|
||||||
'date_type' => 'year_month_day'
|
'date_type' => 'year_month_day',
|
||||||
|
'date_format' => 'MM/DD/YYYY'
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -177,7 +178,8 @@ class SubscriberTest extends MailPoetTest {
|
|||||||
'name' => 'Registered on',
|
'name' => 'Registered on',
|
||||||
'type' => 'date',
|
'type' => 'date',
|
||||||
'params' => array(
|
'params' => array(
|
||||||
'date_type' => 'year_month'
|
'date_type' => 'year_month',
|
||||||
|
'date_format' => 'MM/YYYY'
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -199,7 +201,7 @@ class SubscriberTest extends MailPoetTest {
|
|||||||
expect($subscriber->email)->equals('user.with.cf@mailpoet.com');
|
expect($subscriber->email)->equals('user.with.cf@mailpoet.com');
|
||||||
expect($subscriber->{'cf_'.$custom_field->id})->equals('Paris');
|
expect($subscriber->{'cf_'.$custom_field->id})->equals('Paris');
|
||||||
// date specified as array gets converted to string
|
// date specified as array gets converted to string
|
||||||
expect($subscriber->{'cf_'.$custom_field_2->id})->equals('1984-03-09');
|
expect($subscriber->{'cf_'.$custom_field_2->id})->equals('1984-03-09 00:00:00');
|
||||||
// date specified as string is stored as is
|
// date specified as string is stored as is
|
||||||
expect($subscriber->{'cf_'.$custom_field_3->id})->equals('2013-07');
|
expect($subscriber->{'cf_'.$custom_field_3->id})->equals('2013-07');
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use MailPoet\Models\CustomField;
|
||||||
use MailPoet\Models\Subscriber;
|
use MailPoet\Models\Subscriber;
|
||||||
use MailPoet\Models\Segment;
|
use MailPoet\Models\Segment;
|
||||||
use MailPoet\Models\SubscriberCustomField;
|
use MailPoet\Models\SubscriberCustomField;
|
||||||
@@ -9,6 +10,13 @@ use MailPoet\Util\Helpers;
|
|||||||
|
|
||||||
class ImportTest extends MailPoetTest {
|
class ImportTest extends MailPoetTest {
|
||||||
function _before() {
|
function _before() {
|
||||||
|
$custom_field = CustomField::create();
|
||||||
|
$custom_field->name = 'country';
|
||||||
|
$custom_field->type = 'text';
|
||||||
|
$custom_field->save();
|
||||||
|
$this->subscriber_custom_fields = array((string)$custom_field->id);
|
||||||
|
$this->segment_1 = Segment::createOrUpdate(array('name' => 'Segment 1'));
|
||||||
|
$this->segment_2 = Segment::createOrUpdate(array('name' => 'Segment 2'));
|
||||||
$this->data = array(
|
$this->data = array(
|
||||||
'subscribers' => array(
|
'subscribers' => array(
|
||||||
array(
|
array(
|
||||||
@@ -25,13 +33,13 @@ class ImportTest extends MailPoetTest {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
'columns' => array(
|
'columns' => array(
|
||||||
'first_name' => 0,
|
'first_name' => array('index' => 0),
|
||||||
'last_name' => 1,
|
'last_name' => array('index' => 1),
|
||||||
'email' => 2,
|
'email' => array('index' => 2),
|
||||||
777 => 3
|
(string)$custom_field->id => array('index' => 3)
|
||||||
),
|
),
|
||||||
'segments' => array(
|
'segments' => array(
|
||||||
195
|
$this->segment_1->id
|
||||||
),
|
),
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'updateSubscribers' => true
|
'updateSubscribers' => true
|
||||||
@@ -41,10 +49,6 @@ class ImportTest extends MailPoetTest {
|
|||||||
'last_name',
|
'last_name',
|
||||||
'email'
|
'email'
|
||||||
);
|
);
|
||||||
$this->segment_1 = Segment::createOrUpdate(array('name' => 'Segment 1'));
|
|
||||||
$this->segment_2 = Segment::createOrUpdate(array('name' => 'Segment 2'));
|
|
||||||
|
|
||||||
$this->subscriber_custom_fields = array(777);
|
|
||||||
$this->import = new Import($this->data);
|
$this->import = new Import($this->data);
|
||||||
$this->subscribers_data = $this->import->transformSubscribersData(
|
$this->subscribers_data = $this->import->transformSubscribersData(
|
||||||
$this->data['subscribers'],
|
$this->data['subscribers'],
|
||||||
@@ -63,13 +67,14 @@ class ImportTest extends MailPoetTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testItCanTransformSubscribers() {
|
function testItCanTransformSubscribers() {
|
||||||
|
$custom_field = $this->subscriber_custom_fields[0];
|
||||||
expect($this->import->subscribers_data['first_name'][0])
|
expect($this->import->subscribers_data['first_name'][0])
|
||||||
->equals($this->data['subscribers'][0][0]);
|
->equals($this->data['subscribers'][0][0]);
|
||||||
expect($this->import->subscribers_data['last_name'][0])
|
expect($this->import->subscribers_data['last_name'][0])
|
||||||
->equals($this->data['subscribers'][0][1]);
|
->equals($this->data['subscribers'][0][1]);
|
||||||
expect($this->import->subscribers_data['email'][0])
|
expect($this->import->subscribers_data['email'][0])
|
||||||
->equals($this->data['subscribers'][0][2]);
|
->equals($this->data['subscribers'][0][2]);
|
||||||
expect($this->import->subscribers_data['777'][0])
|
expect($this->import->subscribers_data[$custom_field][0])
|
||||||
->equals($this->data['subscribers'][0][3]);
|
->equals($this->data['subscribers'][0][3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,6 +247,7 @@ class ImportTest extends MailPoetTest {
|
|||||||
|
|
||||||
function testItCanCreateOrUpdateCustomFields() {
|
function testItCanCreateOrUpdateCustomFields() {
|
||||||
$subscribers_data = $this->subscribers_data;
|
$subscribers_data = $this->subscribers_data;
|
||||||
|
$custom_field = $this->subscriber_custom_fields[0];
|
||||||
$this->import->createOrUpdateSubscribers(
|
$this->import->createOrUpdateSubscribers(
|
||||||
'create',
|
'create',
|
||||||
$subscribers_data,
|
$subscribers_data,
|
||||||
@@ -266,8 +272,8 @@ class ImportTest extends MailPoetTest {
|
|||||||
$subscriber_custom_fields = SubscriberCustomField::findArray();
|
$subscriber_custom_fields = SubscriberCustomField::findArray();
|
||||||
expect(count($subscriber_custom_fields))->equals(2);
|
expect(count($subscriber_custom_fields))->equals(2);
|
||||||
expect($subscriber_custom_fields[0]['value'])
|
expect($subscriber_custom_fields[0]['value'])
|
||||||
->equals($subscribers_data[777][0]);
|
->equals($subscribers_data[$custom_field][0]);
|
||||||
$subscribers_data[777][1] = 'Rio';
|
$subscribers_data[$custom_field][1] = 'Rio';
|
||||||
$this->import->createOrUpdateCustomFields(
|
$this->import->createOrUpdateCustomFields(
|
||||||
'update',
|
'update',
|
||||||
$db_subscribers,
|
$db_subscribers,
|
||||||
@@ -276,7 +282,7 @@ class ImportTest extends MailPoetTest {
|
|||||||
);
|
);
|
||||||
$subscriber_custom_fields = SubscriberCustomField::findArray();
|
$subscriber_custom_fields = SubscriberCustomField::findArray();
|
||||||
expect($subscriber_custom_fields[1]['value'])
|
expect($subscriber_custom_fields[1]['value'])
|
||||||
->equals($subscribers_data[777][1]);
|
->equals($subscribers_data[$custom_field][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -320,7 +326,7 @@ class ImportTest extends MailPoetTest {
|
|||||||
|
|
||||||
function testItCanUpdateSubscribers() {
|
function testItCanUpdateSubscribers() {
|
||||||
$result = $this->import->process();
|
$result = $this->import->process();
|
||||||
expect($result['data']['updated'])->equals(0);
|
expect($result['data']['updated'])->equals(0);
|
||||||
$result = $this->import->process();
|
$result = $this->import->process();
|
||||||
expect($result['data']['updated'])->equals(2);
|
expect($result['data']['updated'])->equals(2);
|
||||||
$this->import->update_subscribers = false;
|
$this->import->update_subscribers = false;
|
||||||
@@ -345,6 +351,7 @@ class ImportTest extends MailPoetTest {
|
|||||||
ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
||||||
ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
||||||
ORM::raw_execute('TRUNCATE ' . SubscriberSegment::$_table);
|
ORM::raw_execute('TRUNCATE ' . SubscriberSegment::$_table);
|
||||||
|
ORM::raw_execute('TRUNCATE ' . CustomField::$_table);
|
||||||
ORM::raw_execute('TRUNCATE ' . SubscriberCustomField::$_table);
|
ORM::raw_execute('TRUNCATE ' . SubscriberCustomField::$_table);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -92,7 +92,7 @@
|
|||||||
{{#show_and_match_columns .}}
|
{{#show_and_match_columns .}}
|
||||||
{{#.}}
|
{{#.}}
|
||||||
<th>
|
<th>
|
||||||
<select class="mailpoet_subscribers_column_data_match" id="{{column_id}}" data-column-id="{{column_id}}" id="column_{{@index}}">
|
<select class="mailpoet_subscribers_column_data_match" data-column-id="{{column_id}}" data-validation-rule="false" id="column_{{@index}}">
|
||||||
</th>
|
</th>
|
||||||
{{/.}}
|
{{/.}}
|
||||||
{{/show_and_match_columns}}
|
{{/show_and_match_columns}}
|
||||||
|
Reference in New Issue
Block a user