Compare commits

..

19 Commits

Author SHA1 Message Date
2add301b9f Bumps up version to 3.0.0-beta.36.1.0 and updates changelog 2017-06-27 16:23:22 -04:00
2d217e416a Merge pull request #960 from mailpoet/fix-build-find
Make build script work on Mac os [MAILPOET-969]
2017-06-27 12:21:25 +03:00
77e0ace951 Merge pull request #961 from mailpoet/post_notification_unit_test_update
Updates the way we test for next run date in newsletter scheduler [MAILPOET-967]
2017-06-27 11:42:30 +03:00
933749f8f0 Merge pull request #941 from mailpoet/mp2tomp3migration
Mp2tomp3migration phase 2
2017-06-26 18:47:58 +03:00
7b13babf3f Merge pull request #958 from mailpoet/improve-ajax-errors
Improve ajax errors [MAILPOET-929]
2017-06-26 17:31:15 +03:00
8c673f78d7 Make build script work on Mac os
[MAILPOET-969]
2017-06-26 15:00:48 +01:00
2285c08c01 Revert "Revert "Improve ajax errors [MAILPOET-929]""
This reverts commit 81c3e2facf.
2017-06-26 13:51:53 +01:00
836b7179e9 Improve ajax errors on form submission
[MAILPOET-929]
2017-06-26 13:43:32 +01:00
f89a728c38 Uses predetermined timestamps from which next run date is calculated 2017-06-24 15:59:28 -04:00
58f2c32362 Allows passing custom time value to calculate the next run date from 2017-06-24 15:59:17 -04:00
5bd6c6533a Fixed: Skip button is vanishinig by itself in seconds 2017-06-21 19:24:07 +02:00
f539860922 Remove trailing spaces 2017-06-21 19:24:06 +02:00
536267c8f5 Fixed: Form fields were not inactive when used 2017-06-21 19:24:05 +02:00
5b905a60e8 Fixed: Unit test testReplaceMP2Shortcodes 2017-06-21 19:24:05 +02:00
5e152ebaa1 Fixed: Wrong date format on front-end 2017-06-21 19:24:04 +02:00
2c35c7061e Fixed: Display "Invalid e-mail" on the front-end whereas the e-mail is correct 2017-06-21 19:24:03 +02:00
2515dcf4ce Fixed: Wrong HTML encoding of the text fields 2017-06-21 19:24:02 +02:00
9458bf7418 Add Unit tests for MP2 to MP3 migration phase 2 2017-06-21 19:24:01 +02:00
44bf4b98b8 MP2 to MP3 migration phase 2: Forms migration 2017-06-21 19:24:01 +02:00
13 changed files with 516 additions and 119 deletions

View File

@ -1,74 +1,85 @@
define('ajax', ['mailpoet', 'jquery', 'underscore'], function(MailPoet, jQuery, _) {
'use strict';
MailPoet.Ajax = {
version: 0.5,
options: {},
defaults: {
url: null,
api_version: null,
endpoint: null,
action: null,
token: null,
data: {}
},
post: function(options) {
return this.request('post', options);
},
init: function(options) {
// merge options
this.options = jQuery.extend({}, this.defaults, options);
// set default url
if(this.options.url === null) {
this.options.url = ajaxurl;
}
// set default token
if(this.options.token === null) {
this.options.token = window.mailpoet_token;
}
},
getParams: function() {
return {
action: 'mailpoet',
api_version: this.options.api_version,
token: this.options.token,
endpoint: this.options.endpoint,
method: this.options.action,
data: this.options.data || {}
}
},
request: function(method, options) {
// set options
this.init(options);
// set request params
var params = this.getParams();
var deferred = jQuery.Deferred();
// remove null values from the data object
if (_.isObject(params.data)) {
params.data = _.pick(params.data, function(value) {
return (value !== null)
})
}
// ajax request
deferred = jQuery.post(
this.options.url,
params,
null,
'json'
).then(function(data) {
return data;
}, function(xhr) {
return xhr.responseJSON;
});
// clear options
this.options = {};
return deferred;
}
};
});
function requestFailed(errorMessage, xhr) {
if (xhr.responseJSON) {
return xhr.responseJSON;
}
var message = errorMessage.replace("%d", xhr.status);
return {
errors: [
{
message: message
}
]
}
}
define('ajax', ['mailpoet', 'jquery', 'underscore'], function(MailPoet, jQuery, _) {
MailPoet.Ajax = {
version: 0.5,
options: {},
defaults: {
url: null,
api_version: null,
endpoint: null,
action: null,
token: null,
data: {}
},
post: function(options) {
return this.request('post', options);
},
init: function(options) {
// merge options
this.options = jQuery.extend({}, this.defaults, options);
// set default url
if(this.options.url === null) {
this.options.url = ajaxurl;
}
// set default token
if(this.options.token === null) {
this.options.token = window.mailpoet_token;
}
},
getParams: function() {
return {
action: 'mailpoet',
api_version: this.options.api_version,
token: this.options.token,
endpoint: this.options.endpoint,
method: this.options.action,
data: this.options.data || {}
}
},
request: function(method, options) {
// set options
this.init(options);
// set request params
var params = this.getParams();
// remove null values from the data object
if (_.isObject(params.data)) {
params.data = _.pick(params.data, function(value) {
return (value !== null)
})
}
// ajax request
var deferred = jQuery.post(
this.options.url,
params,
null,
'json'
).then(function(data) {
return data;
}, _.partial(requestFailed, MailPoet.I18n.t('ajaxFailedErrorMessage')));
// clear options
this.options = {};
return deferred;
}
};
});

View File

@ -61,7 +61,7 @@ define('mp2migrator', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
}
jQuery('#progressbar').progressbar('option', 'value', progress);
jQuery('#progresslabel').html(progress + '%');
if(Number(result.current !== 0)) {
if(Number(result.current) !== 0) {
jQuery('#skip-import').hide();
}
if(MailPoet.MP2Migrator.is_logging) {

View File

@ -38,10 +38,17 @@ rm -Rf $plugin_name/assets/js/src
rm -Rf $plugin_name/lang/*.po
# Remove extra files (docs, examples,...) from 3rd party extensions
unameString=`uname`
if [[ "$unameString" == 'Darwin' ]]; then
findCommand='find -E '
else
findCommand='find -regextype posix-egrep '
fi
echo '[BUILD] Removing obsolete files from vendor libraries'
find $plugin_name/vendor -type f -regextype posix-egrep -iregex ".*\/*\.(markdown|md|txt)" -print0 | xargs -0 rm -f
find $plugin_name/vendor -type f -regextype posix-egrep -iregex ".*\/(readme|license|version|changes|changelog)" -print0 | xargs -0 rm -f
find $plugin_name/vendor -type d -regextype posix-egrep -iregex ".*\/(docs?|examples?|\.git)" -print0 | xargs -0 rm -rf
$findCommand $plugin_name/vendor -type f -iregex ".*\/*\.(markdown|md|txt)" -print0 | xargs -0 rm -f
$findCommand $plugin_name/vendor -type f -iregex ".*\/(readme|license|version|changes|changelog)" -print0 | xargs -0 rm -f
$findCommand $plugin_name/vendor -type d -iregex ".*\/(docs?|examples?|\.git)" -print0 | xargs -0 rm -rf
# Remove unit tests from 3rd party extensions
echo '[BUILD] Removing unit tests from vendor libraries'

View File

@ -3,6 +3,7 @@
namespace MailPoet\Config;
use MailPoet\Util\ProgressBar;
use MailPoet\Models\Form;
use MailPoet\Models\Setting;
use MailPoet\Models\Segment;
use MailPoet\Models\Subscriber;
@ -159,12 +160,13 @@ class MP2Migrator {
$this->importSegments();
$this->importCustomFields();
$this->importSubscribers();
$this->importForms();
if(!$this->importStopped()) {
Setting::setValue('mailpoet_migration_complete', true);
$this->log(__('IMPORT COMPLETE', 'mailpoet'));
}
$this->log(sprintf('=== ' . __('END IMPORT', 'mailpoet') . ' %s ===', $datetime->formatTime(time(), \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT)));
$result = ob_get_contents();
ob_clean();
@ -199,6 +201,7 @@ class MP2Migrator {
private function resetMigrationCounters() {
Setting::setValue('last_imported_user_id', 0);
Setting::setValue('last_imported_list_id', 0);
Setting::setValue('last_imported_form_id', 0);
}
/**
@ -262,17 +265,17 @@ class MP2Migrator {
$total_count += $users_count;
$result .= sprintf(_n('%d subscriber', '%d subscribers', $users_count, 'mailpoet'), $users_count) . "\n";
// Forms
$forms_count = \ORM::for_table(MP2_FORM_TABLE)->count();
$total_count += $forms_count;
$result .= sprintf(_n('%d form', '%d forms', $forms_count, 'mailpoet'), $forms_count) . "\n";
// TODO to reactivate during the next phases
/*
// Emails
$emails_count = \ORM::for_table(MP2_EMAIL_TABLE)->count();
$total_count += $emails_count;
$result .= sprintf(_n('%d newsletter', '%d newsletters', $emails_count, 'mailpoet'), $emails_count) . "\n";
// Forms
$forms_count = \ORM::for_table(MP2_FORM_TABLE)->count();
$total_count += $forms_count;
$result .= sprintf(_n('%d form', '%d forms', $forms_count, 'mailpoet'), $forms_count) . "\n";
*/
$this->progressbar->setTotalCount($total_count);
@ -310,7 +313,7 @@ class MP2Migrator {
} while(($lists != null) && ($lists_count > 0));
$this->segments_mapping = $this->getImportedMapping('segments');
$this->log(sprintf(_n("%d segment imported", "%d segments imported", $imported_segments_count, 'mailpoet'), $imported_segments_count));
}
@ -424,7 +427,7 @@ class MP2Migrator {
'id' => $custom_field['id'],
'name' => $custom_field['name'],
'type' => $this->mapCustomFieldType($custom_field['type']),
'params' => $this->mapCustomFieldParams($custom_field),
'params' => $this->mapCustomFieldParams($custom_field['name'], unserialize($custom_field['settings'])),
);
$custom_field = new CustomField();
$custom_field->createOrUpdate($data);
@ -443,6 +446,9 @@ class MP2Migrator {
case 'input':
$type = 'text';
break;
case 'list':
$type = 'segment';
break;
default:
$type = $mp2_type;
}
@ -452,17 +458,42 @@ class MP2Migrator {
/**
* Map the MailPoet 2 custom field settings with the MailPoet custom field params
*
* @param array $custom_field MP2 custom field
* @param string $name Parameter name
* @param array $params MP2 parameters
* @return string serialized MP3 custom field params
*/
private function mapCustomFieldParams($custom_field) {
$params = unserialize($custom_field['settings']);
$params['label'] = $custom_field['name'];
private function mapCustomFieldParams($name, $params) {
if(!isset($params['label'])) {
$params['label'] = $name;
}
if(isset($params['required'])) {
$params['required'] = (bool)$params['required'];
}
if(isset($params['validate'])) {
$params['validate'] = $this->mapCustomFieldValidateValue($params['validate']);
}
if(isset($params['date_order'])) { // Convert the date_order field
$params['date_format'] = strtoupper($params['date_order']);
switch($params['date_type']) {
case 'year_month':
if(preg_match('/y$/i', $params['date_order'])) {
$params['date_format'] = 'MM/YYYY';
} else {
$params['date_format'] = 'YYYY/MM';
}
break;
case 'month';
$params['date_format'] = 'MM';
break;
case 'year';
$params['date_format'] = 'YYYY';
break;
default:
$params['date_format'] = strtoupper($params['date_order']);
}
unset($params['date_order']);
}
return $params;
@ -739,4 +770,195 @@ class MP2Migrator {
return $mappings;
}
/**
* Import the forms
*
*/
private function importForms() {
$imported_forms_count = 0;
if($this->importStopped()) {
return;
}
$this->log(__("Importing forms...", 'mailpoet'));
do {
if($this->importStopped()) {
break;
}
$forms = $this->getForms(self::CHUNK_SIZE);
$forms_count = count($forms);
if(is_array($forms)) {
foreach($forms as $form) {
$new_form = $this->importForm($form);
if(!empty($new_form)) {
$imported_forms_count++;
}
}
}
$this->progressbar->incrementCurrentCount($forms_count);
} while(($forms != null) && ($forms_count > 0));
$this->log(sprintf(_n("%d form imported", "%d forms imported", $imported_forms_count, 'mailpoet'), $imported_forms_count));
}
/**
* Get the Mailpoet 2 forms
*
* @global object $wpdb
* @param int $limit Number of forms max
* @return array Forms
*/
private function getForms($limit) {
global $wpdb;
$forms = array();
$last_id = Setting::getValue('last_imported_form_id', 0);
$table = MP2_FORM_TABLE;
$sql = "
SELECT f.*
FROM `$table` f
WHERE f.form_id > '$last_id'
ORDER BY f.form_id
LIMIT $limit
";
$forms = $wpdb->get_results($sql, ARRAY_A);
return $forms;
}
/**
* Import a form
*
* @param array $form_data Form data
* @return Form
*/
private function importForm($form_data) {
$serialized_data = base64_decode($form_data['data']);
$data = unserialize($serialized_data);
$settings = $data['settings'];
$body = $data['body'];
$segments = $this->getMappedSegmentIds($settings['lists']);
$mp3_form_settings = array(
'on_success' => $settings['on_success'],
'success_message' => $settings['success_message'],
'segments_selected_by' => $settings['lists_selected_by'],
'segments' => $segments,
);
$mp3_form_body = array();
foreach($body as $field) {
$type = $this->mapCustomFieldType($field['type']);
if($type == 'segment') {
$field_id = 'segments';
} else {
switch($field['field']) {
case 'firstname':
$field_id = 'first_name';
break;
case 'lastname':
$field_id = 'last_name';
break;
default:
$field_id = $field['field'];
}
}
$field_id = preg_replace('/^cf_(\d+)$/', '$1', $field_id);
$params = $this->mapCustomFieldParams($field['name'], $field['params']);
if(isset($params['text'])) {
$params['text'] = $this->replaceMP2Shortcodes(html_entity_decode($params['text']));
}
if(isset($params['values'])) {
$params['values'] = $this->replaceListIds($params['values']);
}
$mp3_form_body[] = array(
'type' => $type,
'name' => $field['name'],
'id' => $field_id,
'unique' => !in_array($field['type'], array('html', 'divider', 'email', 'submit'))? "1" : "0",
'static' => in_array($field_id, array('email', 'submit'))? "1" : "0",
'params' => $params,
'position' => isset($field['position'])? $field['position'] : '',
);
}
$form = Form::createOrUpdate(array(
'name' => $form_data['name'],
'body' => $mp3_form_body,
'settings' => $mp3_form_settings,
));
Setting::setValue('last_imported_form_id', $form_data['form_id']);
return $form;
}
/**
* Get the MP3 segments IDs of the MP2 lists IDs
*
* @param array $mp2_list_ids
*/
private function getMappedSegmentIds($mp2_list_ids) {
$mp3_segment_ids = array();
foreach($mp2_list_ids as $list_id) {
if(isset($this->segments_mapping[$list_id])) {
$mp3_segment_ids[] = $this->segments_mapping[$list_id];
}
}
return $mp3_segment_ids;
}
/**
* Replace the MP2 shortcodes used in the textarea fields
*
* @param string $text Text
* @return string Text
*/
private function replaceMP2Shortcodes($text) {
$text = str_replace('[total_subscribers]', '[mailpoet_subscribers_count]', $text);
$text = preg_replace_callback('/\[wysija_subscribers_count list_id="(.*)" \]/', array($this, 'replaceMP2ShortcodesCallback'), $text);
return $text;
}
/**
* Callback function for MP2 shortcodes replacement
*
* @param array $matches PREG matches
* @return string Replacement
*/
private function replaceMP2ShortcodesCallback($matches) {
if(!empty($matches)) {
$mp2_lists = explode(',', $matches[1]);
$segments = $this->getMappedSegmentIds($mp2_lists);
$segments_ids = implode(',', $segments);
return '[mailpoet_subscribers_count segments=' . $segments_ids . ']';
}
}
/**
* Replace the MP2 list IDs by MP3 segment IDs
*
* @param array $values Field values
* @return array Field values
*/
private function replaceListIds($values) {
$mp3_values = array();
foreach($values as $value) {
$mp3_value = array();
foreach($value as $item => $item_value) {
if(($item == 'list_id') && isset($this->segments_mapping[$item_value])) {
$segment_id = $this->segments_mapping[$item_value];
$mp3_value['id'] = $segment_id;
$segment = Segment::findOne($segment_id);
if(isset($segment)) {
$mp3_value['name'] = $segment->get('name');
}
} else {
$mp3_value[$item] = $item_value;
}
}
if(!empty($mp3_value)) {
$mp3_values[] = $mp3_value;
}
}
return $mp3_values;
}
}

View File

@ -112,6 +112,13 @@ class Widget {
'ajax_url' => admin_url('admin-ajax.php'),
'is_rtl' => (function_exists('is_rtl') ? (bool)is_rtl() : false)
));
$ajaxFailedErrorMessage = __('An error has happened while performing a request, please try again later.');
wp_add_inline_script(
'mailpoet_public',
sprintf('MailPoet.I18n.add("ajaxFailedErrorMessage", "%s")', $ajaxFailedErrorMessage),
'after'
);
}
function setupAdminWidgetPageDependencies() {

View File

@ -160,10 +160,11 @@ class Scheduler {
return $relation->value;
}
static function getNextRunDate($schedule) {
static function getNextRunDate($schedule, $from_timestamp = false) {
$from_timestamp = ($from_timestamp) ? $from_timestamp : current_time('timestamp');
try {
$schedule = \Cron\CronExpression::factory($schedule);
$next_run_date = $schedule->getNextRunDate(Carbon::createFromTimestamp(current_time('timestamp')))
$next_run_date = $schedule->getNextRunDate(Carbon::createFromTimestamp($from_timestamp))
->format('Y-m-d H:i:s');
} catch(\Exception $e) {
$next_run_date = false;

View File

@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
/*
* Plugin Name: MailPoet
* Version: 3.0.0-beta.36.0.1
* Version: 3.0.0-beta.36.1.0
* Plugin URI: http://www.mailpoet.com
* Description: Create and send beautiful email newsletters, autoresponders, and post notifications without leaving WordPress. This is a beta version of our brand new plugin!
* Author: MailPoet
@ -21,7 +21,7 @@ if(!defined('ABSPATH')) exit;
*/
$mailpoet_plugin = array(
'version' => '3.0.0-beta.36.0.1',
'version' => '3.0.0-beta.36.1.0',
'filename' => __FILE__,
'path' => dirname(__FILE__),
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',

View File

@ -3,7 +3,7 @@ Contributors: mailpoet, wysija
Tags: newsletter, email, welcome email, post notification, autoresponder, signup, subscription, SMTP
Requires at least: 4.6
Tested up to: 4.8
Stable tag: 3.0.0-beta.36.0.1
Stable tag: 3.0.0-beta.36.1.0
Create and send beautiful emails and newsletters from WordPress.
== Description ==
@ -91,6 +91,10 @@ Our [support site](https://beta.docs.mailpoet.com) has plenty of articles. You c
== Changelog ==
= 3.0.0-beta.36.1.0 - 2017-06-27 =
* Improved: error notices are displayed when AJAX requests fail;
* Added: MailPoet 2 forms are migrated when MailPoet 3 is installed/reinstalled.
= 3.0.0-beta.36.0.1 - 2017-06-23 =
* Improved: preheader will now be hidden in Gmail app;
* Fixed: subscription forms now work without causing "missing file" errors. Thanks Sherrie!

View File

@ -6,7 +6,7 @@ use MailPoet\Models\MappingToExternalEntities;
use MailPoet\Models\Segment;
use MailPoet\Models\Subscriber;
use MailPoet\Models\SubscriberCustomField;
use MailPoet\Models\SubscriberSegment;
use MailPoet\Models\Form;
use Helper\Database;
class MP2MigratorTest extends MailPoetTest {
@ -349,4 +349,151 @@ class MP2MigratorTest extends MailPoetTest {
expect($result[$old_id])->equals($new_id);
}
/**
* Test the importForms function
*
* @global object $wpdb
*/
public function testImportForms() {
global $wpdb;
// Check the forms number
$this->initImport();
$this->loadMP2Fixtures();
$this->invokeMethod($this->MP2Migrator, 'importForms');
expect(Form::count())->equals(2);
// Check a form data
$this->initImport();
$id = 999;
$name = 'Test form';
$list_id = 2;
// Insert a MP2 list
$wpdb->insert($wpdb->prefix . 'wysija_list', array(
'list_id' => $list_id,
'name' => 'Test list',
'description' => 'Test list description',
'is_enabled' => 1,
'is_public' => 1,
'created_at' => 1486319877,
));
$this->invokeMethod($this->MP2Migrator, 'importSegments');
$importedSegmentsMapping = $this->MP2Migrator->getImportedMapping('segments');
// Insert a MP2 form
$data = array(
'version' => 0.4,
'settings' => array(
'on_success' => 'message',
'success_message' => 'Test message',
'lists' => array($list_id),
'lists_selected_by' => 'admin',
),
'body' => array(
array(
'name' => 'E-mail',
'type' => 'input',
'field' => 'email',
'params' => array(
'label' => 'E-mail',
'required' => 1,
),
),
),
);
$wpdb->insert($wpdb->prefix . 'wysija_form', array(
'form_id' => $id,
'name' => $name,
'data' => base64_encode(serialize($data)),
));
$this->invokeMethod($this->MP2Migrator, 'importForms');
$table = MP_FORMS_TABLE;
$form = $wpdb->get_row("SELECT * FROM $table WHERE id=" . 1);
expect($form->name)->equals($name);
$settings = unserialize(($form->settings));
expect($settings['on_success'])->equals('message');
expect($settings['success_message'])->equals('Test message');
expect($settings['segments'][0])->equals($importedSegmentsMapping[$list_id]);
$body = unserialize(($form->body));
expect($body[0]['name'])->equals('E-mail');
expect($body[0]['type'])->equals('text');
}
/**
* Test the replaceMP2Shortcodes function
*
*/
public function testReplaceMP2Shortcodes() {
$this->initImport();
$result = $this->invokeMethod($this->MP2Migrator, 'replaceMP2Shortcodes', array('[total_subscribers]'));
expect($result)->equals('[mailpoet_subscribers_count]');
$result = $this->invokeMethod($this->MP2Migrator, 'replaceMP2Shortcodes', array('Total: [total_subscribers]'));
expect($result)->equals('Total: [mailpoet_subscribers_count]');
$result = $this->invokeMethod($this->MP2Migrator, 'replaceMP2Shortcodes', array('Total: [total_subscribers] found'));
expect($result)->equals('Total: [mailpoet_subscribers_count] found');
$result = $this->invokeMethod($this->MP2Migrator, 'replaceMP2Shortcodes', array('[wysija_subscribers_count list_id="1,2" ]'));
expect($result)->notEquals('mailpoet_subscribers_count segments=1,2');
$this->loadMP2Fixtures();
$this->invokeMethod($this->MP2Migrator, 'importSegments');
$result = $this->invokeMethod($this->MP2Migrator, 'replaceMP2Shortcodes', array('[wysija_subscribers_count list_id="1,2" ]'));
$importedSegmentsMapping = $this->MP2Migrator->getImportedMapping('segments');
expect($result)->equals(sprintf('[mailpoet_subscribers_count segments=%d,%d]', $importedSegmentsMapping[1], $importedSegmentsMapping[2]));
}
/**
* Test the getMappedSegmentIds function
*
*/
public function testGetMappedSegmentIds() {
$this->initImport();
$lists = array(1, 2);
$this->loadMP2Fixtures();
$this->invokeMethod($this->MP2Migrator, 'importSegments');
$importedSegmentsMapping = $this->MP2Migrator->getImportedMapping('segments');
$result = $this->invokeMethod($this->MP2Migrator, 'getMappedSegmentIds', array($lists));
$expected_lists = array($importedSegmentsMapping[1],$importedSegmentsMapping[2]);
expect($result)->equals($expected_lists);
}
/**
* Test the replaceListIds function
*
*/
public function testReplaceListIds() {
$this->initImport();
$lists = array(
array(
'list_id' => 1,
'name' => 'List 1',
),
array(
'list_id' => 2,
'name' => 'List 2',
),
);
$this->loadMP2Fixtures();
$this->invokeMethod($this->MP2Migrator, 'importSegments');
$importedSegmentsMapping = $this->MP2Migrator->getImportedMapping('segments');
$result = $this->invokeMethod($this->MP2Migrator, 'replaceListIds', array($lists));
$expected_lists = array(
array(
'id' => $importedSegmentsMapping[1],
'name' => 'List 1',
),
array(
'id' => $importedSegmentsMapping[2],
'name' => 'List 2',
),
);
expect($result)->equals($expected_lists);
}
}

View File

@ -330,8 +330,9 @@ class NewsletterSchedulerTest extends MailPoetTest {
$newsletter_option = NewsletterOption::where('newsletter_id', $newsletter->id)
->where('option_field_id', $newsletter_option_field->id)
->findOne();
expect(Scheduler::getNextRunDate($newsletter_option->value))
->contains('14:00:00');
$current_time = 1483275600; // Sunday, 1 January 2017 @ 1:00pm (UTC)
expect(Scheduler::getNextRunDate($newsletter_option->value, $current_time))
->equals('2017-01-01 14:00:00');
// weekly notification is scheduled every Tuesday at 14:00
$newsletter = (object)array(
@ -347,11 +348,9 @@ class NewsletterSchedulerTest extends MailPoetTest {
$newsletter_option = NewsletterOption::where('newsletter_id', $newsletter->id)
->where('option_field_id', $newsletter_option_field->id)
->findOne();
$next_run_date = ($current_time->dayOfWeek === Carbon::TUESDAY && $current_time->hour < 14) ?
$current_time :
$current_time->next(Carbon::TUESDAY);
expect(Scheduler::getNextRunDate($newsletter_option->value))
->equals($next_run_date->format('Y-m-d 14:00:00'));
$current_time = 1483275600; // Sunday, 1 January 2017 @ 1:00pm (UTC)
expect(Scheduler::getNextRunDate($newsletter_option->value, $current_time))
->equals('2017-01-03 14:00:00');
// monthly notification is scheduled every 20th day at 14:00
$newsletter = (object)array(
@ -363,12 +362,12 @@ class NewsletterSchedulerTest extends MailPoetTest {
'timeOfDay' => 50400 // 14:00
);
Scheduler::processPostNotificationSchedule($newsletter);
$current_time = Carbon::createFromTimestamp(current_time('timestamp'));
$newsletter_option = NewsletterOption::where('newsletter_id', $newsletter->id)
->where('option_field_id', $newsletter_option_field->id)
->findOne();
expect(Scheduler::getNextRunDate($newsletter_option->value))
->contains('-19 14:00:00');
$current_time = 1483275600; // Sunday, 1 January 2017 @ 1:00pm (UTC)
expect(Scheduler::getNextRunDate($newsletter_option->value, $current_time))
->equals('2017-01-19 14:00:00');
// monthly notification is scheduled every last Saturday at 14:00
$newsletter = (object)array(
@ -380,17 +379,12 @@ class NewsletterSchedulerTest extends MailPoetTest {
'timeOfDay' => 50400 // 14:00
);
Scheduler::processPostNotificationSchedule($newsletter);
$current_time = Carbon::createFromTimestamp(current_time('timestamp'));
$next_run_date = (
$current_time->day <= $current_time->lastOfMonth(Carbon::SATURDAY)->day &&
$current_time->hour < '14'
) ? $current_time->lastOfMonth(Carbon::SATURDAY)
: $current_time->copy()->addMonth()->lastOfMonth(Carbon::SATURDAY);
$newsletter_option = NewsletterOption::where('newsletter_id', $newsletter->id)
->where('option_field_id', $newsletter_option_field->id)
->findOne();
expect(Scheduler::getNextRunDate($newsletter_option->value))
->equals($next_run_date->format('Y-m-d 14:00:00'));
$current_time = 1485694800; // Sunday, 29 January 2017 @ 1:00pm (UTC)
expect(Scheduler::getNextRunDate($newsletter_option->value, $current_time))
->equals('2017-02-25 14:00:00');
// notification is scheduled immediately (next minute)
$newsletter = (object)array(
@ -402,12 +396,12 @@ class NewsletterSchedulerTest extends MailPoetTest {
'timeOfDay' => null
);
Scheduler::processPostNotificationSchedule($newsletter);
$current_time = Carbon::createFromTimestamp(current_time('timestamp'));
$newsletter_option = NewsletterOption::where('newsletter_id', $newsletter->id)
->where('option_field_id', $newsletter_option_field->id)
->findOne();
expect(Scheduler::getNextRunDate($newsletter_option->value))
->equals($current_time->addMinute()->format('Y-m-d H:i:00'));
$current_time = 1483275600; // Sunday, 1 January 2017 @ 1:00pm (UTC)
expect(Scheduler::getNextRunDate($newsletter_option->value, $current_time))
->equals('2017-01-01 13:01:00');
}
function _createQueue(

View File

@ -55,6 +55,9 @@ jQuery('.toplevel_page_mailpoet-newsletters.menu-top-last')
'mailpoet.js'
)%>
<%= localize({
'ajaxFailedErrorMessage': __('An error has happened while performing a request, the server has responded with response code %d'),
}) %>
<% block translations %><% endblock %>
<% block after_translations %><% endblock %>

View File

@ -10,8 +10,8 @@
<h3><%= __('What will be kept in MailPoet 3') %></h3>
<ul>
<li><strong><%= __('Subscribers and lists') %> <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/2.2.1/svg/2714.svg"></strong></li>
<li><strong><%= __('Forms') %> <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/2.2.1/svg/2714.svg"></strong></li>
<li><%= __('Settings') %> (<%= __('soon') %>!)</li>
<li><%= __('Forms') %> (<%= __('soon') %>!)</li>
<li><%= __('Archive of sent newsletters') %> (<%= __('soon') %>!)</li>
</ul>

View File

@ -248,6 +248,7 @@ var publicConfig = {
entry: {
public: [
'mailpoet',
'i18n',
'ajax',
'iframe',
'jquery.serialize_object',