MailPoet Newsletters (New) - Version 3.5.1

Version Description

  • 2018-03-13 =
  • Improved: email validation for WordPress user synchronization;
  • Fixed: import no longer discards e-mails with dashes. A big thank-you to everyone who reported the issue;
  • Fixed: sending does not get stuck on the last step of the newsletter creation process. Thanks, Ren!
Download this release

Release Info

Developer wysija
Plugin Icon 128x128 MailPoet Newsletters (New)
Version 3.5.1
Comparing to
See all releases

Code changes from version 3.5.0 to 3.5.1

assets/js/{admin.7f9ea640.js → admin.e01d2225.js} RENAMED
@@ -11622,7 +11622,10 @@ webpackJsonp([0],[
11622
  }, {
11623
  name: 'reply_to_address',
11624
  type: 'text',
11625
- placeholder: MailPoet.I18n.t('replyToAddressPlaceholder')
 
 
 
11626
  }]
11627
  }];
11628
 
@@ -12131,7 +12134,10 @@ webpackJsonp([0],[
12131
  }, {
12132
  name: 'reply_to_address',
12133
  type: 'text',
12134
- placeholder: MailPoet.I18n.t('replyToAddressPlaceholder')
 
 
 
12135
  }]
12136
  }, {
12137
  name: 'options',
@@ -12216,7 +12222,10 @@ webpackJsonp([0],[
12216
  }, {
12217
  name: 'reply_to_address',
12218
  type: 'text',
12219
- placeholder: MailPoet.I18n.t('replyToAddressPlaceholder')
 
 
 
12220
  }]
12221
  }];
12222
 
@@ -22042,8 +22051,9 @@ webpackJsonp([0],[
22042
  // is the email in 'mailto:email' format?
22043
  email = test[1].trim();
22044
  }
22045
- // test for valid characters using WP's rule (https://core.trac.wordpress.org/browser/tags/4.7.3/src/wp-includes/formatting.php#L2902)
22046
- if (!/^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-@]+$/.test(email)) {
 
22047
  return false;
22048
  }
22049
  return email;
@@ -22087,7 +22097,7 @@ webpackJsonp([0],[
22087
  for (column in rowData) {
22088
  emailAddress = detectAndCleanupEmail(rowData[column]);
22089
  if (emailColumnPosition === null
22090
- && window.emailRegex.test(emailAddress)) {
22091
  emailColumnPosition = column;
22092
  // add current e-mail to an object index
22093
  parsedEmails[emailAddress] = true;
@@ -22107,7 +22117,7 @@ webpackJsonp([0],[
22107
  if (_.has(parsedEmails, email)) {
22108
  duplicateEmails.push(email);
22109
  }
22110
- else if (!window.emailRegex.test(email)) {
22111
  invalidEmails.push(rowData[emailColumnPosition]);
22112
  }
22113
  // if we haven't yet processed this e-mail and it passed
@@ -22135,7 +22145,7 @@ webpackJsonp([0],[
22135
  // since we assume that the header line is always present, we need
22136
  // to detect the header by checking if it contains a valid e-mail address
22137
  window.importData.step1 = {
22138
- header: (!window.emailRegex.test(
22139
  processedSubscribers[0][emailColumnPosition])
22140
  ) ? processedSubscribers.shift() : null,
22141
  subscribers: processedSubscribers,
@@ -22568,7 +22578,7 @@ webpackJsonp([0],[
22568
  columnData = helperSubscribers.subscribers[0][i];
22569
  columnId = 'ignore'; // set default column type
22570
  // if the column is not undefined and has a valid e-mail, set type as email
22571
- if (columnData % 1 !== 0 && window.emailRegex.test(columnData)) {
22572
  columnId = 'email';
22573
  } else if (helperSubscribers.header) {
22574
  headerName = helperSubscribers.header[i];
@@ -22669,7 +22679,9 @@ webpackJsonp([0],[
22669
  // EMAIL filter: if the first value in the column doesn't have a valid
22670
  // email, hide the next button
22671
  if (column.id === 'email') {
22672
- if (!window.emailRegex.test(subscribersClone.subscribers[0][matchedColumn.index])) {
 
 
22673
  preventNextStep = true;
22674
  if (!jQuery('[data-id="notice_invalidEmail"]').length) {
22675
  MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidElement'), {
11622
  }, {
11623
  name: 'reply_to_address',
11624
  type: 'text',
11625
+ placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
11626
+ validation: {
11627
+ 'data-parsley-type': 'email'
11628
+ }
11629
  }]
11630
  }];
11631
 
12134
  }, {
12135
  name: 'reply_to_address',
12136
  type: 'text',
12137
+ placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
12138
+ validation: {
12139
+ 'data-parsley-type': 'email'
12140
+ }
12141
  }]
12142
  }, {
12143
  name: 'options',
12222
  }, {
12223
  name: 'reply_to_address',
12224
  type: 'text',
12225
+ placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
12226
+ validation: {
12227
+ 'data-parsley-type': 'email'
12228
+ }
12229
  }]
12230
  }];
12231
 
22051
  // is the email in 'mailto:email' format?
22052
  email = test[1].trim();
22053
  }
22054
+
22055
+ // validate email
22056
+ if (!window.mailpoet_email_regex.test(email)) {
22057
  return false;
22058
  }
22059
  return email;
22097
  for (column in rowData) {
22098
  emailAddress = detectAndCleanupEmail(rowData[column]);
22099
  if (emailColumnPosition === null
22100
+ && window.mailpoet_email_regex.test(emailAddress)) {
22101
  emailColumnPosition = column;
22102
  // add current e-mail to an object index
22103
  parsedEmails[emailAddress] = true;
22117
  if (_.has(parsedEmails, email)) {
22118
  duplicateEmails.push(email);
22119
  }
22120
+ else if (!window.mailpoet_email_regex.test(email)) {
22121
  invalidEmails.push(rowData[emailColumnPosition]);
22122
  }
22123
  // if we haven't yet processed this e-mail and it passed
22145
  // since we assume that the header line is always present, we need
22146
  // to detect the header by checking if it contains a valid e-mail address
22147
  window.importData.step1 = {
22148
+ header: (!window.mailpoet_email_regex.test(
22149
  processedSubscribers[0][emailColumnPosition])
22150
  ) ? processedSubscribers.shift() : null,
22151
  subscribers: processedSubscribers,
22578
  columnData = helperSubscribers.subscribers[0][i];
22579
  columnId = 'ignore'; // set default column type
22580
  // if the column is not undefined and has a valid e-mail, set type as email
22581
+ if (columnData % 1 !== 0 && window.mailpoet_email_regex.test(columnData)) {
22582
  columnId = 'email';
22583
  } else if (helperSubscribers.header) {
22584
  headerName = helperSubscribers.header[i];
22679
  // EMAIL filter: if the first value in the column doesn't have a valid
22680
  // email, hide the next button
22681
  if (column.id === 'email') {
22682
+ if (!window.mailpoet_email_regex.test(
22683
+ subscribersClone.subscribers[0][matchedColumn.index])
22684
+ ) {
22685
  preventNextStep = true;
22686
  if (!jQuery('[data-id="notice_invalidEmail"]').length) {
22687
  MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidElement'), {
assets/js/{admin_vendor.b56c5496.js → admin_vendor.73a171d4.js} RENAMED
@@ -40486,7 +40486,7 @@ webpackJsonp([1],[
40486
  _extends({
40487
  name: this.props.field.name,
40488
  id: 'field_' + this.props.field.name,
40489
- value: this.props.item[this.props.field.name],
40490
  onChange: this.props.onValueChange
40491
  }, this.props.field.validation),
40492
  placeholder,
40486
  _extends({
40487
  name: this.props.field.name,
40488
  id: 'field_' + this.props.field.name,
40489
+ value: this.props.item[this.props.field.name] || '',
40490
  onChange: this.props.onValueChange
40491
  }, this.props.field.validation),
40492
  placeholder,
assets/js/lib/mailpoet_shortcodes/plugin.js CHANGED
@@ -8,35 +8,33 @@
8
  * its placeholder into editor text.
9
  */
10
 
11
- /* jshint unused:false */
12
- /* global tinymce:true */
13
- tinymce.PluginManager.add('mailpoet_shortcodes', function (editor) { // eslint-disable-line func-names
14
- var appendLabelAndClose = function (shortcode) { // eslint-disable-line func-names
15
- editor.insertContent(shortcode);
16
- editor.windowManager.close();
17
- };
18
- var generateOnClickFunc = function (shortcode) { // eslint-disable-line func-names
19
- return function () { // eslint-disable-line func-names
20
- appendLabelAndClose(shortcode);
 
21
  };
22
- };
23
 
24
  editor.addButton('mailpoet_shortcodes', {
25
  icon: 'mailpoet_shortcodes',
26
- onclick: function () { // eslint-disable-line func-names
27
- var shortcodes = [];
28
- var configShortcodes = editor.settings.mailpoet_shortcodes;
29
- var segment;
30
- var i;
31
 
32
- for (segment in configShortcodes) {
33
  if (configShortcodes.hasOwnProperty(segment)) {
34
  shortcodes.push({
35
  type: 'label',
36
  text: segment
37
  });
38
 
39
- for (i = 0; i < configShortcodes[segment].length; i += 1) {
40
  shortcodes.push({
41
  type: 'button',
42
  text: configShortcodes[segment][i].text,
8
  * its placeholder into editor text.
9
  */
10
 
11
+ /*jshint unused:false */
12
+ /*global tinymce:true */
13
+ tinymce.PluginManager.add('mailpoet_shortcodes', function(editor, url) {
14
+ var appendLabelAndClose = function(shortcode) {
15
+ editor.insertContent(shortcode);
16
+ editor.windowManager.close();
17
+ },
18
+ generateOnClickFunc = function(shortcode) {
19
+ return function() {
20
+ appendLabelAndClose(shortcode);
21
+ };
22
  };
 
23
 
24
  editor.addButton('mailpoet_shortcodes', {
25
  icon: 'mailpoet_shortcodes',
26
+ onclick: function() {
27
+ var shortcodes = [],
28
+ configShortcodes = editor.settings.mailpoet_shortcodes;
 
 
29
 
30
+ for (var segment in configShortcodes) {
31
  if (configShortcodes.hasOwnProperty(segment)) {
32
  shortcodes.push({
33
  type: 'label',
34
  text: segment
35
  });
36
 
37
+ for (var i = 0; i < configShortcodes[segment].length; i += 1) {
38
  shortcodes.push({
39
  type: 'button',
40
  text: configShortcodes[segment][i].text,
assets/js/manifest.json CHANGED
@@ -1,10 +1,10 @@
1
  {
2
  "mp2migrator.js": "mp2migrator.d90426c2.js",
3
  "public.js": "public.ec1bce32.js",
4
- "admin.js": "admin.7f9ea640.js",
5
- "admin_vendor.js": "admin_vendor.b56c5496.js",
6
  "form_editor.js": "form_editor.20737db0.js",
7
  "mailpoet.js": "mailpoet.4267d9a6.js",
8
  "newsletter_editor.js": "newsletter_editor.fd18ee48.js",
9
- "vendor.js": "vendor.79f8bb9d.js"
10
  }
1
  {
2
  "mp2migrator.js": "mp2migrator.d90426c2.js",
3
  "public.js": "public.ec1bce32.js",
4
+ "admin.js": "admin.e01d2225.js",
5
+ "admin_vendor.js": "admin_vendor.73a171d4.js",
6
  "form_editor.js": "form_editor.20737db0.js",
7
  "mailpoet.js": "mailpoet.4267d9a6.js",
8
  "newsletter_editor.js": "newsletter_editor.fd18ee48.js",
9
+ "vendor.js": "vendor.98a3aa8c.js"
10
  }
assets/js/{vendor.79f8bb9d.js → vendor.98a3aa8c.js} RENAMED
@@ -76,7 +76,7 @@
76
  /******/ script.charset = 'utf-8';
77
  /******/ script.async = true;
78
 
79
- /******/ script.src = __webpack_require__.p + "" + ({"0":"admin","1":"admin_vendor","2":"form_editor","3":"mailpoet","4":"newsletter_editor"}[chunkId]||chunkId) + "." + {"0":"7f9ea640","1":"b56c5496","2":"20737db0","3":"4267d9a6","4":"fd18ee48"}[chunkId] + ".chunk.js";
80
  /******/ head.appendChild(script);
81
  /******/ }
82
  /******/ };
76
  /******/ script.charset = 'utf-8';
77
  /******/ script.async = true;
78
 
79
+ /******/ script.src = __webpack_require__.p + "" + ({"0":"admin","1":"admin_vendor","2":"form_editor","3":"mailpoet","4":"newsletter_editor"}[chunkId]||chunkId) + "." + {"0":"e01d2225","1":"73a171d4","2":"20737db0","3":"4267d9a6","4":"fd18ee48"}[chunkId] + ".chunk.js";
80
  /******/ head.appendChild(script);
81
  /******/ }
82
  /******/ };
lang/mailpoet-ca.mo CHANGED
Binary file
lang/mailpoet-da_DK.mo CHANGED
Binary file
lang/mailpoet-de_DE.mo CHANGED
Binary file
lang/mailpoet-en_GB.mo ADDED
Binary file
lang/mailpoet-es_ES.mo CHANGED
Binary file
lang/mailpoet-fa_IR.mo CHANGED
Binary file
lang/mailpoet-fr_CA.mo CHANGED
Binary file
lang/mailpoet-fr_FR.mo CHANGED
Binary file
lang/mailpoet-it_IT.mo CHANGED
Binary file
lang/mailpoet-ja.mo CHANGED
Binary file
lang/mailpoet-nl_NL.mo CHANGED
Binary file
lang/mailpoet-pl_PL.mo CHANGED
Binary file
lang/mailpoet-pt_BR.mo CHANGED
Binary file
lang/mailpoet-pt_PT.mo CHANGED
Binary file
lang/mailpoet-ru_RU.mo CHANGED
Binary file
lang/mailpoet-sq.mo CHANGED
Binary file
lang/mailpoet-sv_SE.mo CHANGED
Binary file
lang/mailpoet-tr_TR.mo CHANGED
Binary file
lang/mailpoet.pot CHANGED
@@ -4,7 +4,7 @@ msgid ""
4
  msgstr ""
5
  "Project-Id-Version: \n"
6
  "Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
7
- "POT-Creation-Date: 2018-03-06 13:51:22+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -299,7 +299,7 @@ msgstr ""
299
  msgid "Manage segments"
300
  msgstr ""
301
 
302
- #: lib/Config/Capabilities.php:67 lib/Config/Menu.php:642 views/premium.html:41
303
  msgid "MailPoet"
304
  msgstr ""
305
 
@@ -473,7 +473,7 @@ msgstr ""
473
  msgid "Migration"
474
  msgstr ""
475
 
476
- #: lib/Config/Menu.php:562
477
  msgid "In any WordPress role"
478
  msgstr ""
479
 
@@ -1169,62 +1169,62 @@ msgid "Month (January, February,...)"
1169
  msgstr ""
1170
 
1171
  #: lib/Form/Block/Date.php:124 views/newsletters.html:197
1172
- #: views/subscribers/importExport/import.html:56
1173
  msgid "January"
1174
  msgstr ""
1175
 
1176
  #: lib/Form/Block/Date.php:124 views/newsletters.html:198
1177
- #: views/subscribers/importExport/import.html:57
1178
  msgid "February"
1179
  msgstr ""
1180
 
1181
  #: lib/Form/Block/Date.php:124 views/newsletters.html:199
1182
- #: views/subscribers/importExport/import.html:58
1183
  msgid "March"
1184
  msgstr ""
1185
 
1186
  #: lib/Form/Block/Date.php:124 views/newsletters.html:200
1187
- #: views/subscribers/importExport/import.html:59
1188
  msgid "April"
1189
  msgstr ""
1190
 
1191
  #: lib/Form/Block/Date.php:125 views/newsletters.html:201
1192
- #: views/newsletters.html:213 views/subscribers/importExport/import.html:60
1193
  msgid "May"
1194
  msgstr ""
1195
 
1196
  #: lib/Form/Block/Date.php:125 views/newsletters.html:202
1197
- #: views/subscribers/importExport/import.html:61
1198
  msgid "June"
1199
  msgstr ""
1200
 
1201
  #: lib/Form/Block/Date.php:125 views/newsletters.html:203
1202
- #: views/subscribers/importExport/import.html:62
1203
  msgid "July"
1204
  msgstr ""
1205
 
1206
  #: lib/Form/Block/Date.php:125 views/newsletters.html:204
1207
- #: views/subscribers/importExport/import.html:63
1208
  msgid "August"
1209
  msgstr ""
1210
 
1211
  #: lib/Form/Block/Date.php:125 views/newsletters.html:205
1212
- #: views/subscribers/importExport/import.html:64
1213
  msgid "September"
1214
  msgstr ""
1215
 
1216
  #: lib/Form/Block/Date.php:126 views/newsletters.html:206
1217
- #: views/subscribers/importExport/import.html:65
1218
  msgid "October"
1219
  msgstr ""
1220
 
1221
  #: lib/Form/Block/Date.php:126 views/newsletters.html:207
1222
- #: views/subscribers/importExport/import.html:66
1223
  msgid "November"
1224
  msgstr ""
1225
 
1226
  #: lib/Form/Block/Date.php:126 views/newsletters.html:208
1227
- #: views/subscribers/importExport/import.html:67
1228
  msgid "December"
1229
  msgstr ""
1230
 
@@ -1584,15 +1584,15 @@ msgstr ""
1584
  msgid "Not In Segment"
1585
  msgstr ""
1586
 
1587
- #: lib/Subscribers/ImportExport/Import/Import.php:68
1588
  msgid "Missing or invalid import data."
1589
  msgstr ""
1590
 
1591
- #: lib/Subscribers/ImportExport/Import/Import.php:89
1592
  msgid "No valid subscribers were found."
1593
  msgstr ""
1594
 
1595
- #: lib/Subscribers/ImportExport/Import/Import.php:129
1596
  msgid "Unable to save imported subscribers."
1597
  msgstr ""
1598
 
@@ -1655,7 +1655,7 @@ msgid "System fields"
1655
  msgstr ""
1656
 
1657
  #: lib/Subscribers/ImportExport/ImportExportFactory.php:112
1658
- #: views/subscribers/importExport/import.html:52
1659
  msgid "User fields"
1660
  msgstr ""
1661
 
@@ -1894,7 +1894,7 @@ msgstr ""
1894
  msgid "Saved! Add this form to %1$sa widget%2$s."
1895
  msgstr ""
1896
 
1897
- #: views/form/editor.html:587 views/subscribers/importExport/import.html:50
1898
  msgid "Add new field"
1899
  msgstr ""
1900
 
@@ -1923,7 +1923,7 @@ msgid "Edit display"
1923
  msgstr ""
1924
 
1925
  #: views/form/templates/blocks/segment.hbs:2
1926
- #: views/subscribers/importExport/import.html:48
1927
  msgid "Please select at least one list"
1928
  msgstr ""
1929
 
@@ -2373,13 +2373,13 @@ msgstr ""
2373
  msgid "Visit MailPoet.com to purchase a key"
2374
  msgstr ""
2375
 
2376
- #: views/layout.html:60
2377
  msgid ""
2378
  "An error has happened while performing a request, the server has responded "
2379
  "with response code %d"
2380
  msgstr ""
2381
 
2382
- #: views/layout.html:87
2383
  msgid ""
2384
  "Want to give feedback to the MailPoet team? Contact us here. Please provide "
2385
  "as much information as possible!"
@@ -3281,7 +3281,7 @@ msgid "%d emails were permanently deleted."
3281
  msgstr ""
3282
 
3283
  #: views/newsletters.html:47 views/subscribers/importExport/import/step2.html:8
3284
- #: views/subscribers/importExport/import.html:47
3285
  #: views/subscribers/subscribers.html:40
3286
  msgid "Show more details"
3287
  msgstr ""
@@ -4925,11 +4925,15 @@ msgstr ""
4925
  msgid "Save settings"
4926
  msgstr ""
4927
 
4928
- #: views/settings.html:108
 
 
 
 
4929
  msgid "Settings saved"
4930
  msgstr ""
4931
 
4932
- #: views/settings.html:175
4933
  msgid ""
4934
  "Are you sure? All of your MailPoet data will be permanently erased "
4935
  "(newsletters, statistics, subscribers, etc.)."
@@ -4973,7 +4977,7 @@ msgid "Excel file"
4973
  msgstr ""
4974
 
4975
  #: views/subscribers/importExport/export.html:105
4976
- #: views/subscribers/importExport/import.html:36
4977
  msgid "Server error:"
4978
  msgstr ""
4979
 
@@ -5077,118 +5081,118 @@ msgid ""
5077
  "Look at some [link]examples on our support site[/link]."
5078
  msgstr ""
5079
 
5080
- #: views/subscribers/importExport/import.html:35
5081
  msgid "No active lists found"
5082
  msgstr ""
5083
 
5084
- #: views/subscribers/importExport/import.html:37
5085
  msgid "Select"
5086
  msgstr ""
5087
 
5088
- #: views/subscribers/importExport/import.html:39
5089
  msgid "Only comma-separated (CSV) file formats are supported."
5090
  msgstr ""
5091
 
5092
- #: views/subscribers/importExport/import.html:40
5093
  msgid ""
5094
  "Your CSV is over %s and is too big to process. Please split the file into "
5095
  "two or more sections."
5096
  msgstr ""
5097
 
5098
- #: views/subscribers/importExport/import.html:41
5099
  msgid ""
5100
  "Your data could not be processed. Please make sure it is in the correct "
5101
  "format."
5102
  msgstr ""
5103
 
5104
- #: views/subscribers/importExport/import.html:42
5105
  msgid ""
5106
  "No valid records were found. This file needs to be formatted in a CSV style "
5107
  "(comma-separated). Look at some [link]examples on our support site.[/link]"
5108
  msgstr ""
5109
 
5110
- #: views/subscribers/importExport/import.html:43
5111
  msgid "%1$s records had issues and were skipped."
5112
  msgstr ""
5113
 
5114
- #: views/subscribers/importExport/import.html:44
5115
  msgid "%1$s emails are not valid: %2$s"
5116
  msgstr ""
5117
 
5118
- #: views/subscribers/importExport/import.html:45
5119
  msgid "%1$s emails appear more than once in your file: %2$s"
5120
  msgstr ""
5121
 
5122
- #: views/subscribers/importExport/import.html:46
5123
  msgid "Hide details"
5124
  msgstr ""
5125
 
 
5126
  #: views/subscribers/importExport/import.html:49
5127
- #: views/subscribers/importExport/import.html:51
5128
  msgid "Add new list"
5129
  msgstr ""
5130
 
5131
- #: views/subscribers/importExport/import.html:53
5132
  msgid "The selected value is already matched to another field."
5133
  msgstr ""
5134
 
5135
- #: views/subscribers/importExport/import.html:54
5136
  msgid "Confirm that this field corresponds to the selected field."
5137
  msgstr ""
5138
 
5139
- #: views/subscribers/importExport/import.html:55
5140
  msgid ""
5141
  "One of the fields contains an invalid email. Please fix it before "
5142
  "continuing."
5143
  msgstr ""
5144
 
5145
- #: views/subscribers/importExport/import.html:68
5146
  msgid ""
5147
  "Do not match as a 'date field' if most of the rows for that field return "
5148
  "the same error."
5149
  msgstr ""
5150
 
5151
- #: views/subscribers/importExport/import.html:69
5152
  msgid "First row date cannot be empty."
5153
  msgstr ""
5154
 
5155
- #: views/subscribers/importExport/import.html:70
5156
  msgid "Verify that the date in blue matches the original date."
5157
  msgstr ""
5158
 
5159
- #: views/subscribers/importExport/import.html:71
5160
  msgid "PM"
5161
  msgstr ""
5162
 
5163
- #: views/subscribers/importExport/import.html:72
5164
  msgid "AM"
5165
  msgstr ""
5166
 
5167
- #: views/subscribers/importExport/import.html:73
5168
  msgid "Error matching date"
5169
  msgstr ""
5170
 
5171
- #: views/subscribers/importExport/import.html:74
5172
  msgid "One of the fields contains an invalid date. Please fix before continuing."
5173
  msgstr ""
5174
 
5175
- #: views/subscribers/importExport/import.html:75
5176
  msgid "Error adding a new list:"
5177
  msgstr ""
5178
 
5179
- #: views/subscribers/importExport/import.html:76
5180
  msgid "One of the fields contains an invalid email. Please fix before continuing."
5181
  msgstr ""
5182
 
5183
- #: views/subscribers/importExport/import.html:77
5184
  msgid "Custom field could not be created"
5185
  msgstr ""
5186
 
5187
- #: views/subscribers/importExport/import.html:78
5188
  msgid "%1$s subscribers added to %2$s."
5189
  msgstr ""
5190
 
5191
- #: views/subscribers/importExport/import.html:79
5192
  msgid "%1$s existing subscribers were updated and added to %2$s."
5193
  msgstr ""
5194
 
@@ -5363,11 +5367,47 @@ msgstr ""
5363
  msgid "View all changes"
5364
  msgstr ""
5365
 
5366
- #: views/update.html:34
5367
  msgid "Care to Give Your Opinion?"
5368
  msgstr ""
5369
 
5370
- #: views/update.html:59 views/welcome.html:60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5371
  msgid "Awesome! Now, take me to MailPoet"
5372
  msgstr ""
5373
 
4
  msgstr ""
5
  "Project-Id-Version: \n"
6
  "Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
7
+ "POT-Creation-Date: 2018-03-13 23:32:30+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
299
  msgid "Manage segments"
300
  msgstr ""
301
 
302
+ #: lib/Config/Capabilities.php:67 lib/Config/Menu.php:645 views/premium.html:41
303
  msgid "MailPoet"
304
  msgstr ""
305
 
473
  msgid "Migration"
474
  msgstr ""
475
 
476
+ #: lib/Config/Menu.php:565
477
  msgid "In any WordPress role"
478
  msgstr ""
479
 
1169
  msgstr ""
1170
 
1171
  #: lib/Form/Block/Date.php:124 views/newsletters.html:197
1172
+ #: views/subscribers/importExport/import.html:54
1173
  msgid "January"
1174
  msgstr ""
1175
 
1176
  #: lib/Form/Block/Date.php:124 views/newsletters.html:198
1177
+ #: views/subscribers/importExport/import.html:55
1178
  msgid "February"
1179
  msgstr ""
1180
 
1181
  #: lib/Form/Block/Date.php:124 views/newsletters.html:199
1182
+ #: views/subscribers/importExport/import.html:56
1183
  msgid "March"
1184
  msgstr ""
1185
 
1186
  #: lib/Form/Block/Date.php:124 views/newsletters.html:200
1187
+ #: views/subscribers/importExport/import.html:57
1188
  msgid "April"
1189
  msgstr ""
1190
 
1191
  #: lib/Form/Block/Date.php:125 views/newsletters.html:201
1192
+ #: views/newsletters.html:213 views/subscribers/importExport/import.html:58
1193
  msgid "May"
1194
  msgstr ""
1195
 
1196
  #: lib/Form/Block/Date.php:125 views/newsletters.html:202
1197
+ #: views/subscribers/importExport/import.html:59
1198
  msgid "June"
1199
  msgstr ""
1200
 
1201
  #: lib/Form/Block/Date.php:125 views/newsletters.html:203
1202
+ #: views/subscribers/importExport/import.html:60
1203
  msgid "July"
1204
  msgstr ""
1205
 
1206
  #: lib/Form/Block/Date.php:125 views/newsletters.html:204
1207
+ #: views/subscribers/importExport/import.html:61
1208
  msgid "August"
1209
  msgstr ""
1210
 
1211
  #: lib/Form/Block/Date.php:125 views/newsletters.html:205
1212
+ #: views/subscribers/importExport/import.html:62
1213
  msgid "September"
1214
  msgstr ""
1215
 
1216
  #: lib/Form/Block/Date.php:126 views/newsletters.html:206
1217
+ #: views/subscribers/importExport/import.html:63
1218
  msgid "October"
1219
  msgstr ""
1220
 
1221
  #: lib/Form/Block/Date.php:126 views/newsletters.html:207
1222
+ #: views/subscribers/importExport/import.html:64
1223
  msgid "November"
1224
  msgstr ""
1225
 
1226
  #: lib/Form/Block/Date.php:126 views/newsletters.html:208
1227
+ #: views/subscribers/importExport/import.html:65
1228
  msgid "December"
1229
  msgstr ""
1230
 
1584
  msgid "Not In Segment"
1585
  msgstr ""
1586
 
1587
+ #: lib/Subscribers/ImportExport/Import/Import.php:69
1588
  msgid "Missing or invalid import data."
1589
  msgstr ""
1590
 
1591
+ #: lib/Subscribers/ImportExport/Import/Import.php:90
1592
  msgid "No valid subscribers were found."
1593
  msgstr ""
1594
 
1595
+ #: lib/Subscribers/ImportExport/Import/Import.php:130
1596
  msgid "Unable to save imported subscribers."
1597
  msgstr ""
1598
 
1655
  msgstr ""
1656
 
1657
  #: lib/Subscribers/ImportExport/ImportExportFactory.php:112
1658
+ #: views/subscribers/importExport/import.html:50
1659
  msgid "User fields"
1660
  msgstr ""
1661
 
1894
  msgid "Saved! Add this form to %1$sa widget%2$s."
1895
  msgstr ""
1896
 
1897
+ #: views/form/editor.html:587 views/subscribers/importExport/import.html:48
1898
  msgid "Add new field"
1899
  msgstr ""
1900
 
1923
  msgstr ""
1924
 
1925
  #: views/form/templates/blocks/segment.hbs:2
1926
+ #: views/subscribers/importExport/import.html:46
1927
  msgid "Please select at least one list"
1928
  msgstr ""
1929
 
2373
  msgid "Visit MailPoet.com to purchase a key"
2374
  msgstr ""
2375
 
2376
+ #: views/layout.html:62
2377
  msgid ""
2378
  "An error has happened while performing a request, the server has responded "
2379
  "with response code %d"
2380
  msgstr ""
2381
 
2382
+ #: views/layout.html:89
2383
  msgid ""
2384
  "Want to give feedback to the MailPoet team? Contact us here. Please provide "
2385
  "as much information as possible!"
3281
  msgstr ""
3282
 
3283
  #: views/newsletters.html:47 views/subscribers/importExport/import/step2.html:8
3284
+ #: views/subscribers/importExport/import.html:45
3285
  #: views/subscribers/subscribers.html:40
3286
  msgid "Show more details"
3287
  msgstr ""
4925
  msgid "Save settings"
4926
  msgstr ""
4927
 
4928
+ #: views/settings.html:73
4929
+ msgid "Invalid email addresses: "
4930
+ msgstr ""
4931
+
4932
+ #: views/settings.html:119
4933
  msgid "Settings saved"
4934
  msgstr ""
4935
 
4936
+ #: views/settings.html:186
4937
  msgid ""
4938
  "Are you sure? All of your MailPoet data will be permanently erased "
4939
  "(newsletters, statistics, subscribers, etc.)."
4977
  msgstr ""
4978
 
4979
  #: views/subscribers/importExport/export.html:105
4980
+ #: views/subscribers/importExport/import.html:34
4981
  msgid "Server error:"
4982
  msgstr ""
4983
 
5081
  "Look at some [link]examples on our support site[/link]."
5082
  msgstr ""
5083
 
5084
+ #: views/subscribers/importExport/import.html:33
5085
  msgid "No active lists found"
5086
  msgstr ""
5087
 
5088
+ #: views/subscribers/importExport/import.html:35
5089
  msgid "Select"
5090
  msgstr ""
5091
 
5092
+ #: views/subscribers/importExport/import.html:37
5093
  msgid "Only comma-separated (CSV) file formats are supported."
5094
  msgstr ""
5095
 
5096
+ #: views/subscribers/importExport/import.html:38
5097
  msgid ""
5098
  "Your CSV is over %s and is too big to process. Please split the file into "
5099
  "two or more sections."
5100
  msgstr ""
5101
 
5102
+ #: views/subscribers/importExport/import.html:39
5103
  msgid ""
5104
  "Your data could not be processed. Please make sure it is in the correct "
5105
  "format."
5106
  msgstr ""
5107
 
5108
+ #: views/subscribers/importExport/import.html:40
5109
  msgid ""
5110
  "No valid records were found. This file needs to be formatted in a CSV style "
5111
  "(comma-separated). Look at some [link]examples on our support site.[/link]"
5112
  msgstr ""
5113
 
5114
+ #: views/subscribers/importExport/import.html:41
5115
  msgid "%1$s records had issues and were skipped."
5116
  msgstr ""
5117
 
5118
+ #: views/subscribers/importExport/import.html:42
5119
  msgid "%1$s emails are not valid: %2$s"
5120
  msgstr ""
5121
 
5122
+ #: views/subscribers/importExport/import.html:43
5123
  msgid "%1$s emails appear more than once in your file: %2$s"
5124
  msgstr ""
5125
 
5126
+ #: views/subscribers/importExport/import.html:44
5127
  msgid "Hide details"
5128
  msgstr ""
5129
 
5130
+ #: views/subscribers/importExport/import.html:47
5131
  #: views/subscribers/importExport/import.html:49
 
5132
  msgid "Add new list"
5133
  msgstr ""
5134
 
5135
+ #: views/subscribers/importExport/import.html:51
5136
  msgid "The selected value is already matched to another field."
5137
  msgstr ""
5138
 
5139
+ #: views/subscribers/importExport/import.html:52
5140
  msgid "Confirm that this field corresponds to the selected field."
5141
  msgstr ""
5142
 
5143
+ #: views/subscribers/importExport/import.html:53
5144
  msgid ""
5145
  "One of the fields contains an invalid email. Please fix it before "
5146
  "continuing."
5147
  msgstr ""
5148
 
5149
+ #: views/subscribers/importExport/import.html:66
5150
  msgid ""
5151
  "Do not match as a 'date field' if most of the rows for that field return "
5152
  "the same error."
5153
  msgstr ""
5154
 
5155
+ #: views/subscribers/importExport/import.html:67
5156
  msgid "First row date cannot be empty."
5157
  msgstr ""
5158
 
5159
+ #: views/subscribers/importExport/import.html:68
5160
  msgid "Verify that the date in blue matches the original date."
5161
  msgstr ""
5162
 
5163
+ #: views/subscribers/importExport/import.html:69
5164
  msgid "PM"
5165
  msgstr ""
5166
 
5167
+ #: views/subscribers/importExport/import.html:70
5168
  msgid "AM"
5169
  msgstr ""
5170
 
5171
+ #: views/subscribers/importExport/import.html:71
5172
  msgid "Error matching date"
5173
  msgstr ""
5174
 
5175
+ #: views/subscribers/importExport/import.html:72
5176
  msgid "One of the fields contains an invalid date. Please fix before continuing."
5177
  msgstr ""
5178
 
5179
+ #: views/subscribers/importExport/import.html:73
5180
  msgid "Error adding a new list:"
5181
  msgstr ""
5182
 
5183
+ #: views/subscribers/importExport/import.html:74
5184
  msgid "One of the fields contains an invalid email. Please fix before continuing."
5185
  msgstr ""
5186
 
5187
+ #: views/subscribers/importExport/import.html:75
5188
  msgid "Custom field could not be created"
5189
  msgstr ""
5190
 
5191
+ #: views/subscribers/importExport/import.html:76
5192
  msgid "%1$s subscribers added to %2$s."
5193
  msgstr ""
5194
 
5195
+ #: views/subscribers/importExport/import.html:77
5196
  msgid "%1$s existing subscribers were updated and added to %2$s."
5197
  msgstr ""
5198
 
5367
  msgid "View all changes"
5368
  msgstr ""
5369
 
5370
+ #: views/update.html:36 views/update.html:65
5371
  msgid "Care to Give Your Opinion?"
5372
  msgstr ""
5373
 
5374
+ #: views/update.html:52
5375
+ msgid "Do you enjoy using MailPoet?"
5376
+ msgstr ""
5377
+
5378
+ #: views/update.html:54
5379
+ msgid ""
5380
+ "If you have the time, we’d really appreciate it if you left us a review on "
5381
+ "the WordPress Plugin Directory."
5382
+ msgstr ""
5383
+
5384
+ #: views/update.html:55
5385
+ msgid "Every star counts."
5386
+ msgstr ""
5387
+
5388
+ #: views/update.html:58
5389
+ msgid "No thanks"
5390
+ msgstr ""
5391
+
5392
+ #: views/update.html:59
5393
+ msgid "Next time"
5394
+ msgstr ""
5395
+
5396
+ #: views/update.html:60
5397
+ msgid "Rate now"
5398
+ msgstr ""
5399
+
5400
+ #: views/update.html:62
5401
+ msgid "Care to share criticism or a feature request instead?"
5402
+ msgstr ""
5403
+
5404
+ #: views/update.html:63
5405
+ msgid ""
5406
+ "Click on the question mark (?) in the blue circle at the bottom right of "
5407
+ "this page to send us a message."
5408
+ msgstr ""
5409
+
5410
+ #: views/update.html:73 views/welcome.html:60
5411
  msgid "Awesome! Now, take me to MailPoet"
5412
  msgstr ""
5413
 
lib/Config/Menu.php CHANGED
@@ -380,10 +380,13 @@ class Menu {
380
  );
381
 
382
  $data['is_new_user'] = true;
 
383
  if(!empty($data['settings']['installed_at'])) {
384
  $installed_at = Carbon::createFromTimestamp(strtotime($data['settings']['installed_at']));
385
  $current_time = Carbon::createFromTimestamp(current_time('timestamp'));
386
  $data['is_new_user'] = $current_time->diffInDays($installed_at) <= 30;
 
 
387
  }
388
 
389
  $readme_file = Env::$path . '/readme.txt';
380
  );
381
 
382
  $data['is_new_user'] = true;
383
+ $data['is_old_user'] = false;
384
  if(!empty($data['settings']['installed_at'])) {
385
  $installed_at = Carbon::createFromTimestamp(strtotime($data['settings']['installed_at']));
386
  $current_time = Carbon::createFromTimestamp(current_time('timestamp'));
387
  $data['is_new_user'] = $current_time->diffInDays($installed_at) <= 30;
388
+ $data['is_old_user'] = $current_time->diffInMonths($installed_at) >= 6;
389
+ $data['stop_call_for_rating'] = isset($data['settings']['stop_call_for_rating']) ? $data['settings']['stop_call_for_rating'] : false;
390
  }
391
 
392
  $readme_file = Env::$path . '/readme.txt';
lib/Config/Migrator.php CHANGED
@@ -174,7 +174,8 @@ class Migrator {
174
  'unconfirmed_data longtext,',
175
  'PRIMARY KEY (id),',
176
  'UNIQUE KEY email (email),',
177
- 'KEY wp_user_id (wp_user_id)',
 
178
  );
179
  return $this->sqlify(__FUNCTION__, $attributes);
180
  }
174
  'unconfirmed_data longtext,',
175
  'PRIMARY KEY (id),',
176
  'UNIQUE KEY email (email),',
177
+ 'KEY wp_user_id (wp_user_id),',
178
+ 'KEY updated_at (updated_at)',
179
  );
180
  return $this->sqlify(__FUNCTION__, $attributes);
181
  }
lib/Cron/Workers/SendingQueue/SendingQueue.php CHANGED
@@ -40,6 +40,8 @@ class SendingQueue {
40
  $queue->delete();
41
  continue;
42
  }
 
 
43
  // configure mailer
44
  $this->mailer_task->configureMailer($newsletter);
45
  // get newsletter segments
@@ -79,7 +81,7 @@ class SendingQueue {
79
  }
80
  $queue = $this->processQueue(
81
  $queue,
82
- $newsletter,
83
  $found_subscribers
84
  );
85
  if($queue->status === SendingQueueModel::STATUS_COMPLETED) {
40
  $queue->delete();
41
  continue;
42
  }
43
+ // clone the original object to be used for processing
44
+ $_newsletter = (object)$newsletter->asArray();
45
  // configure mailer
46
  $this->mailer_task->configureMailer($newsletter);
47
  // get newsletter segments
81
  }
82
  $queue = $this->processQueue(
83
  $queue,
84
+ $_newsletter,
85
  $found_subscribers
86
  );
87
  if($queue->status === SendingQueueModel::STATUS_COMPLETED) {
lib/Models/ModelValidator.php CHANGED
@@ -32,7 +32,7 @@ class ModelValidator extends \Sudzy\Engine {
32
 
33
  function validateEmail($email) {
34
  $permitted_length = (strlen($email) >= self::EMAIL_MIN_LENGTH && strlen($email) <= self::EMAIL_MAX_LENGTH);
35
- $valid_email = (is_email($email) !== false);
36
  return ($permitted_length && $valid_email);
37
  }
38
 
32
 
33
  function validateEmail($email) {
34
  $permitted_length = (strlen($email) >= self::EMAIL_MIN_LENGTH && strlen($email) <= self::EMAIL_MAX_LENGTH);
35
+ $valid_email = is_email($email) !== false && parent::_isEmail($email, null);
36
  return ($permitted_length && $valid_email);
37
  }
38
 
lib/Newsletter/Url.php CHANGED
@@ -12,7 +12,7 @@ class Url {
12
 
13
  static function getViewInBrowserUrl(
14
  $type,
15
- NewsletterModel $newsletter,
16
  $subscriber = false,
17
  $queue = false,
18
  $preview = false
12
 
13
  static function getViewInBrowserUrl(
14
  $type,
15
+ $newsletter,
16
  $subscriber = false,
17
  $queue = false,
18
  $preview = false
lib/Segments/WP.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
  namespace MailPoet\Segments;
3
 
 
4
  use MailPoet\Models\Subscriber;
5
  use MailPoet\Models\Segment;
6
  use MailPoet\Models\SubscriberSegment;
@@ -80,8 +81,9 @@ class WP {
80
 
81
  static function synchronizeUsers() {
82
 
83
- self::updateSubscribersEmails();
84
- self::insertSubscribers();
 
85
  self::removeFromTrash();
86
  self::updateFirstNames();
87
  self::updateLastNames();
@@ -92,20 +94,48 @@ class WP {
92
  return true;
93
  }
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  private static function updateSubscribersEmails() {
96
  global $wpdb;
 
 
 
97
  $subscribers_table = Subscriber::$_table;
98
  Subscriber::raw_execute(sprintf('
99
  UPDATE IGNORE %1$s
100
- JOIN %2$s as wu ON %1$s.wp_user_id = wu.id
101
- SET %1$s.email = wu.user_email
102
- WHERE %1$s.wp_user_id IS NOT NULL AND wu.user_email != ""
103
  ', $subscribers_table, $wpdb->users));
 
 
 
 
 
104
  }
105
 
106
  private static function insertSubscribers() {
107
  global $wpdb;
108
  $subscribers_table = Subscriber::$_table;
 
 
 
 
 
 
 
109
  Subscriber::raw_execute(sprintf('
110
  INSERT IGNORE INTO %1$s(wp_user_id, email, status, created_at)
111
  SELECT wu.id, wu.user_email, "subscribed", CURRENT_TIMESTAMP() FROM %2$s wu
@@ -113,6 +143,8 @@ class WP {
113
  WHERE mps.wp_user_id IS NULL AND wu.user_email != ""
114
  ON DUPLICATE KEY UPDATE wp_user_id = wu.id
115
  ', $subscribers_table, $wpdb->users));
 
 
116
  }
117
 
118
  private static function updateFirstNames() {
1
  <?php
2
  namespace MailPoet\Segments;
3
 
4
+ use MailPoet\Models\ModelValidator;
5
  use MailPoet\Models\Subscriber;
6
  use MailPoet\Models\Segment;
7
  use MailPoet\Models\SubscriberSegment;
81
 
82
  static function synchronizeUsers() {
83
 
84
+ $updated_users_emails = self::updateSubscribersEmails();
85
+ $inserted_users_emails = self::insertSubscribers();
86
+ self::removeUpdatedSubscribersWithInvalidEmail(array_merge($updated_users_emails, $inserted_users_emails));
87
  self::removeFromTrash();
88
  self::updateFirstNames();
89
  self::updateLastNames();
94
  return true;
95
  }
96
 
97
+ private static function removeUpdatedSubscribersWithInvalidEmail($updated_emails) {
98
+ $validator = new ModelValidator();
99
+ $invalid_wp_user_ids = array_map(function($item) {
100
+ return $item['id'];
101
+ },
102
+ array_filter($updated_emails, function($updated_email) use($validator) {
103
+ return !$validator->validateEmail($updated_email['email']);
104
+ }));
105
+ if(!$invalid_wp_user_ids) {
106
+ return;
107
+ }
108
+ \ORM::for_table(Subscriber::$_table)->whereIn('wp_user_id', $invalid_wp_user_ids)->delete_many();
109
+ }
110
+
111
  private static function updateSubscribersEmails() {
112
  global $wpdb;
113
+ Subscriber::raw_execute('SELECT NOW();');
114
+ $start_time = Subscriber::get_last_statement()->fetch(\PDO::FETCH_COLUMN);
115
+
116
  $subscribers_table = Subscriber::$_table;
117
  Subscriber::raw_execute(sprintf('
118
  UPDATE IGNORE %1$s
119
+ INNER JOIN %2$s as wu ON %1$s.wp_user_id = wu.id
120
+ SET %1$s.email = wu.user_email;
 
121
  ', $subscribers_table, $wpdb->users));
122
+
123
+ return \ORM::for_table(Subscriber::$_table)->raw_query(sprintf(
124
+ 'SELECT wp_user_id as id, email FROM %s
125
+ WHERE updated_at >= \'%s\';
126
+ ', $subscribers_table, $start_time))->findArray();
127
  }
128
 
129
  private static function insertSubscribers() {
130
  global $wpdb;
131
  $subscribers_table = Subscriber::$_table;
132
+
133
+ $inserterd_user_ids = \ORM::for_table($wpdb->users)->raw_query(sprintf(
134
+ 'SELECT %2$s.id, %2$s.user_email as email FROM %2$s
135
+ LEFT JOIN %1$s AS mps ON mps.wp_user_id = %2$s.id
136
+ WHERE mps.wp_user_id IS NULL AND %2$s.user_email != ""
137
+ ', $subscribers_table, $wpdb->users))->findArray();
138
+
139
  Subscriber::raw_execute(sprintf('
140
  INSERT IGNORE INTO %1$s(wp_user_id, email, status, created_at)
141
  SELECT wu.id, wu.user_email, "subscribed", CURRENT_TIMESTAMP() FROM %2$s wu
143
  WHERE mps.wp_user_id IS NULL AND wu.user_email != ""
144
  ON DUPLICATE KEY UPDATE wp_user_id = wu.id
145
  ', $subscribers_table, $wpdb->users));
146
+
147
+ return $inserterd_user_ids;
148
  }
149
 
150
  private static function updateFirstNames() {
lib/Subscribers/ImportExport/Import/Import.php CHANGED
@@ -3,6 +3,7 @@ namespace MailPoet\Subscribers\ImportExport\Import;
3
 
4
  use MailPoet\Form\Block\Date;
5
  use MailPoet\Models\CustomField;
 
6
  use MailPoet\Models\Newsletter;
7
  use MailPoet\Models\Subscriber;
8
  use MailPoet\Models\SubscriberCustomField;
@@ -148,12 +149,13 @@ class Import {
148
 
149
  function validateSubscribersData($subscribers_data, $validation_rules) {
150
  $invalid_records = array();
 
151
  foreach($subscribers_data as $column => &$data) {
152
  $validation_rule = $validation_rules[$column];
153
  if($validation_rule === 'email') {
154
  $data = array_map(
155
- function($index, $email) use(&$invalid_records) {
156
- if(!is_email($email)) {
157
  $invalid_records[] = $index;
158
  }
159
  return strtolower($email);
3
 
4
  use MailPoet\Form\Block\Date;
5
  use MailPoet\Models\CustomField;
6
+ use MailPoet\Models\ModelValidator;
7
  use MailPoet\Models\Newsletter;
8
  use MailPoet\Models\Subscriber;
9
  use MailPoet\Models\SubscriberCustomField;
149
 
150
  function validateSubscribersData($subscribers_data, $validation_rules) {
151
  $invalid_records = array();
152
+ $validator = new ModelValidator();
153
  foreach($subscribers_data as $column => &$data) {
154
  $validation_rule = $validation_rules[$column];
155
  if($validation_rule === 'email') {
156
  $data = array_map(
157
+ function($index, $email) use(&$invalid_records, $validator) {
158
+ if(!$validator->validateEmail($email)) {
159
  $invalid_records[] = $index;
160
  }
161
  return strtolower($email);
mailpoet.php CHANGED
@@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
4
 
5
  /*
6
  * Plugin Name: MailPoet 3 (New)
7
- * Version: 3.5.0
8
  * Plugin URI: http://www.mailpoet.com
9
  * Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
10
  * Author: MailPoet
@@ -20,7 +20,7 @@ if(!defined('ABSPATH')) exit;
20
  */
21
 
22
  $mailpoet_plugin = array(
23
- 'version' => '3.5.0',
24
  'filename' => __FILE__,
25
  'path' => dirname(__FILE__),
26
  'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
4
 
5
  /*
6
  * Plugin Name: MailPoet 3 (New)
7
+ * Version: 3.5.1
8
  * Plugin URI: http://www.mailpoet.com
9
  * Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
10
  * Author: MailPoet
20
  */
21
 
22
  $mailpoet_plugin = array(
23
+ 'version' => '3.5.1',
24
  'filename' => __FILE__,
25
  'path' => dirname(__FILE__),
26
  'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: newsletter, email, welcome email, post notification, autoresponder, signup
4
  Requires at least: 4.7
5
  Tested up to: 4.9
6
  Requires PHP: 5.3
7
- Stable tag: 3.5.0
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -116,6 +116,11 @@ Stop by our [support site](https://www.mailpoet.com/support).
116
 
117
  == Changelog ==
118
 
 
 
 
 
 
119
  = 3.5.0 - 2018-03-06 =
120
  * Premium: bulk actions can now be executed on subscribers belonging to a selected segment;
121
  * Improved: a proper error page is displayed if user credentials can't be verified when clicking a tracked newsletter link. Thanks, Bernhard;
4
  Requires at least: 4.7
5
  Tested up to: 4.9
6
  Requires PHP: 5.3
7
+ Stable tag: 3.5.1
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
 
116
 
117
  == Changelog ==
118
 
119
+ = 3.5.1 - 2018-03-13 =
120
+ * Improved: email validation for WordPress user synchronization;
121
+ * Fixed: import no longer discards e-mails with dashes. A big thank-you to everyone who reported the issue;
122
+ * Fixed: sending does not get stuck on the last step of the newsletter creation process. Thanks, René!
123
+
124
  = 3.5.0 - 2018-03-06 =
125
  * Premium: bulk actions can now be executed on subscribers belonging to a selected segment;
126
  * Improved: a proper error page is displayed if user credentials can't be verified when clicking a tracked newsletter link. Thanks, Bernhard;
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit304fcf7f744d8f15317439a24e53ab80::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit172c2bcf023cb1eb88fc8ba92912848b::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit304fcf7f744d8f15317439a24e53ab80
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit304fcf7f744d8f15317439a24e53ab80
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit304fcf7f744d8f15317439a24e53ab80', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit304fcf7f744d8f15317439a24e53ab80', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInit304fcf7f744d8f15317439a24e53ab80::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit304fcf7f744d8f15317439a24e53ab80
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
- $includeFiles = Composer\Autoload\ComposerStaticInit304fcf7f744d8f15317439a24e53ab80::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
- composerRequire304fcf7f744d8f15317439a24e53ab80($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
- function composerRequire304fcf7f744d8f15317439a24e53ab80($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit172c2bcf023cb1eb88fc8ba92912848b
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit172c2bcf023cb1eb88fc8ba92912848b', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit172c2bcf023cb1eb88fc8ba92912848b', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit172c2bcf023cb1eb88fc8ba92912848b::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
+ $includeFiles = Composer\Autoload\ComposerStaticInit172c2bcf023cb1eb88fc8ba92912848b::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequire172c2bcf023cb1eb88fc8ba92912848b($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
+ function composerRequire172c2bcf023cb1eb88fc8ba92912848b($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit304fcf7f744d8f15317439a24e53ab80
8
  {
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@@ -986,10 +986,10 @@ class ComposerStaticInit304fcf7f744d8f15317439a24e53ab80
986
  public static function getInitializer(ClassLoader $loader)
987
  {
988
  return \Closure::bind(function () use ($loader) {
989
- $loader->prefixLengthsPsr4 = ComposerStaticInit304fcf7f744d8f15317439a24e53ab80::$prefixLengthsPsr4;
990
- $loader->prefixDirsPsr4 = ComposerStaticInit304fcf7f744d8f15317439a24e53ab80::$prefixDirsPsr4;
991
- $loader->prefixesPsr0 = ComposerStaticInit304fcf7f744d8f15317439a24e53ab80::$prefixesPsr0;
992
- $loader->classMap = ComposerStaticInit304fcf7f744d8f15317439a24e53ab80::$classMap;
993
 
994
  }, null, ClassLoader::class);
995
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit172c2bcf023cb1eb88fc8ba92912848b
8
  {
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
986
  public static function getInitializer(ClassLoader $loader)
987
  {
988
  return \Closure::bind(function () use ($loader) {
989
+ $loader->prefixLengthsPsr4 = ComposerStaticInit172c2bcf023cb1eb88fc8ba92912848b::$prefixLengthsPsr4;
990
+ $loader->prefixDirsPsr4 = ComposerStaticInit172c2bcf023cb1eb88fc8ba92912848b::$prefixDirsPsr4;
991
+ $loader->prefixesPsr0 = ComposerStaticInit172c2bcf023cb1eb88fc8ba92912848b::$prefixesPsr0;
992
+ $loader->classMap = ComposerStaticInit172c2bcf023cb1eb88fc8ba92912848b::$classMap;
993
 
994
  }, null, ClassLoader::class);
995
  }
views/layout.html CHANGED
@@ -48,6 +48,8 @@ jQuery('.toplevel_page_mailpoet-newsletters.menu-top-last')
48
  var mailpoet_premium_version = <%= json_encode(mailpoet_premium_version()) %>;
49
  var mailpoet_analytics_enabled = <%= is_analytics_enabled() | json_encode %>;
50
  var mailpoet_analytics_data = <%= json_encode(get_analytics_data()) %>;
 
 
51
  </script>
52
 
53
  <!-- javascripts -->
48
  var mailpoet_premium_version = <%= json_encode(mailpoet_premium_version()) %>;
49
  var mailpoet_analytics_enabled = <%= is_analytics_enabled() | json_encode %>;
50
  var mailpoet_analytics_data = <%= json_encode(get_analytics_data()) %>;
51
+ // RFC 5322 standard; http://emailregex.com/ combined with https://google.github.io/closure-library/api/goog.format.EmailAddress.html#isValid
52
+ var mailpoet_email_regex = /(?=^[+a-zA-Z0-9_.!#$%&'*\/=?^`{|}~-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,63}$)(?=^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,})))/;
53
  </script>
54
 
55
  <!-- javascripts -->
views/settings.html CHANGED
@@ -64,6 +64,17 @@
64
  $(function() {
65
  // on form submission
66
  $('#mailpoet_settings_form').on('submit', function() {
 
 
 
 
 
 
 
 
 
 
 
67
  // if reCAPTCHA is enabled but keys are emty, show error
68
  var enabled = $('input[name="re_captcha[enabled]"]:checked').val(),
69
  site_key = $('input[name="re_captcha[site_token]"]').val().trim(),
64
  $(function() {
65
  // on form submission
66
  $('#mailpoet_settings_form').on('submit', function() {
67
+ // Check if filled emails are valid
68
+ var invalidEmails = $.map($('#mailpoet_settings_form')[0].elements, function(el) {
69
+ return el.type === 'email' && el.value && !window.mailpoet_email_regex.test(el.value) ? el.value : null;
70
+ }).filter(function(val) { return !!val; });
71
+ if (invalidEmails.length) {
72
+ MailPoet.Notice.error(
73
+ "<%= __('Invalid email addresses: ') | escape('js') %>" + invalidEmails.join(', '),
74
+ { scroll: true }
75
+ );
76
+ return false;
77
+ }
78
  // if reCAPTCHA is enabled but keys are emty, show error
79
  var enabled = $('input[name="re_captcha[enabled]"]:checked').val(),
80
  site_key = $('input[name="re_captcha[site_token]"]').val().trim(),
views/subscribers/importExport/import.html CHANGED
@@ -24,9 +24,7 @@
24
  importData = {},
25
  mailpoetColumnsSelect2 = <%= subscriberFieldsSelect2|raw %>,
26
  mailpoetColumns = <%= subscriberFields|raw %>,
27
- mailpoetSegments = <%= segments|raw %>,
28
- // RFC 5322 standard; http://emailregex.com/
29
- emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
30
  </script>
31
  <% endblock %>
32
 
24
  importData = {},
25
  mailpoetColumnsSelect2 = <%= subscriberFieldsSelect2|raw %>,
26
  mailpoetColumns = <%= subscriberFields|raw %>,
27
+ mailpoetSegments = <%= segments|raw %>
 
 
28
  </script>
29
  <% endblock %>
30
 
views/update.html CHANGED
@@ -31,9 +31,9 @@
31
  </div>
32
 
33
  <div class="feature-section one-col mailpoet_centered">
34
- <h2><%= __('Care to Give Your Opinion?') %></h2>
35
 
36
  <% if(is_new_user) %>
 
37
  <div class="pd-embed" id="pd_1516701033"></div>
38
  <script type="text/javascript">
39
  var _polldaddy = [] || _polldaddy;
@@ -48,7 +48,21 @@
48
 
49
  (function(d,c,j){if(!document.getElementById(j)){var pd=d.createElement(c),s;pd.id=j;pd.src=('https:'==document.location.protocol)?'https://polldaddy.com/survey.js':'http://i0.poll.fm/survey.js';s=document.getElementsByTagName(c)[0];s.parentNode.insertBefore(pd,s);}}(document,'script','pd-embed'));
50
  </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  <% else %>
 
52
  <script type="text/javascript" charset="utf-8" src="https://secure.polldaddy.com/p/9942888.js"></script>
53
  <noscript><a href="https://polldaddy.com/poll/9942888/">Imagine you could pick just 2 features to be added with our next release. Which ones would they be?</a></noscript>
54
  <% endif %>
@@ -63,6 +77,25 @@
63
 
64
  <script type="text/javascript">
65
  jQuery(function($) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  $(function() {
67
  MailPoet.trackEvent(
68
  'User has updated MailPoet',
@@ -90,5 +123,6 @@
90
 
91
  });
92
 
 
93
  </script>
94
  <% endblock %>
31
  </div>
32
 
33
  <div class="feature-section one-col mailpoet_centered">
 
34
 
35
  <% if(is_new_user) %>
36
+ <h2><%= __('Care to Give Your Opinion?') %></h2>
37
  <div class="pd-embed" id="pd_1516701033"></div>
38
  <script type="text/javascript">
39
  var _polldaddy = [] || _polldaddy;
48
 
49
  (function(d,c,j){if(!document.getElementById(j)){var pd=d.createElement(c),s;pd.id=j;pd.src=('https:'==document.location.protocol)?'https://polldaddy.com/survey.js':'http://i0.poll.fm/survey.js';s=document.getElementsByTagName(c)[0];s.parentNode.insertBefore(pd,s);}}(document,'script','pd-embed'));
50
  </script>
51
+ <% elseif(is_old_user and not stop_call_for_rating) %>
52
+ <h2><%= __('Do you enjoy using MailPoet?') %></h2>
53
+ <p>
54
+ <%= __('If you have the time, we’d really appreciate it if you left us a review on the WordPress Plugin Directory.') %>
55
+ <br><%= __('Every star counts.') %>
56
+
57
+ <p>
58
+ <a class="button" id="no-thanks"><%= __('No thanks') %></a>
59
+ <a class="button" href="admin.php?page=mailpoet-newsletters"><%= __('Next time') %></a>
60
+ <a class="button button-primary" id="rate-now" href="https://wordpress.org/support/plugin/mailpoet/reviews/?rate=5#new-post" target="_blank"><%= __('Rate now') %></a>
61
+ <p>
62
+ <%= __('Care to share criticism or a feature request instead?') %>
63
+ <br><%= __('Click on the question mark (?) in the blue circle at the bottom right of this page to send us a message.') %>
64
  <% else %>
65
+ <h2><%= __('Care to Give Your Opinion?') %></h2>
66
  <script type="text/javascript" charset="utf-8" src="https://secure.polldaddy.com/p/9942888.js"></script>
67
  <noscript><a href="https://polldaddy.com/poll/9942888/">Imagine you could pick just 2 features to be added with our next release. Which ones would they be?</a></noscript>
68
  <% endif %>
77
 
78
  <script type="text/javascript">
79
  jQuery(function($) {
80
+ function stopShowingCallForRating() {
81
+ return MailPoet.Ajax.post({
82
+ api_version: window.mailpoet_api_version,
83
+ endpoint: 'settings',
84
+ action: 'set',
85
+ data: {
86
+ stop_call_for_rating: true,
87
+ }
88
+ });
89
+ }
90
+ $('#no-thanks').click(function (e) {
91
+ e.preventDefault();
92
+ stopShowingCallForRating().done(function () {
93
+ window.location.href = 'admin.php?page=mailpoet-newsletters';
94
+ });
95
+ return false;
96
+ });
97
+ $('#rate-now').click(stopShowingCallForRating);
98
+
99
  $(function() {
100
  MailPoet.trackEvent(
101
  'User has updated MailPoet',
123
 
124
  });
125
 
126
+
127
  </script>
128
  <% endblock %>