MailPoet Newsletters (New) - Version 3.0.0-beta.37.0.0

Version Description

  • 2017-07-25 =
  • Improved: we collect more informative data from those who share it with us in order to improve the plugin. You should share too!
  • Fixed: deleted WordPress users are removed from the WordPress Users list as well;
  • Fixed: shortcodes for custom fields are now inserted correctly in the email designer;
  • Fixed: MailPoet Sending Service stays activated after saving Settings;
  • Fixed: improperly rendered newsletters will not be sent. Thanks Scott and Alison!
Download this release

Release Info

Developer wysija
Plugin Icon 128x128 MailPoet Newsletters (New)
Version 3.0.0-beta.37.0.0
Comparing to
See all releases

Code changes from version 3.0.0-beta.36.3.1 to 3.0.0-beta.37.0.0

Files changed (48) hide show
  1. assets/css/{admin.06d5a0b9.css → admin.71690c62.css} +32 -18
  2. assets/css/manifest.json +1 -1
  3. assets/js/{admin.f15adcea.js → admin.607dbf77.js} +23 -7
  4. assets/js/{admin_vendor.e019c409.js → admin_vendor.ea8adfbb.js} +4 -0
  5. assets/js/{form_editor.e0b22679.js → form_editor.81d8f2a0.js} +8 -19
  6. assets/js/{mailpoet.0ebf4b66.js → mailpoet.5fb06233.js} +0 -0
  7. assets/js/manifest.json +7 -7
  8. assets/js/{newsletter_editor.cec09cf2.js → newsletter_editor.1d7ae8a6.js} +0 -0
  9. assets/js/{public.0e89cdab.js → public.5a1e5874.js} +0 -0
  10. assets/js/{vendor.6d57818a.js → vendor.25e2ce6a.js} +1 -1
  11. lang/index.php +3 -0
  12. lang/mailpoet.pot +89 -86
  13. lib/Analytics/Reporter.php +36 -5
  14. lib/Config/Database.php +2 -0
  15. lib/Config/Initializer.php +5 -4
  16. lib/Config/Migrator.php +12 -4
  17. lib/Cron/Workers/Bounce.php +12 -25
  18. lib/Cron/Workers/SendingQueue/SendingQueue.php +2 -2
  19. lib/Cron/Workers/SendingQueue/Tasks/Newsletter.php +34 -15
  20. lib/Models/Model.php +29 -22
  21. lib/Models/ModelValidator.php +10 -2
  22. lib/Models/ScheduledTask.php +2 -69
  23. lib/Models/ScheduledTaskSubscriber.php +58 -0
  24. lib/Models/SendingQueue.php +13 -6
  25. lib/Newsletter/Shortcodes/ShortcodesHelper.php +1 -1
  26. lib/Segments/WP.php +11 -7
  27. lib/Settings/Pages.php +15 -0
  28. lib/Tasks/Bounce.php +28 -0
  29. lib/Tasks/Subscribers.php +48 -0
  30. lib/Tasks/Subscribers/BatchIterator.php +61 -0
  31. lib/Tasks/Subscribers/index.php +0 -0
  32. lib/Tasks/index.php +0 -0
  33. lib/Twig/Functions.php +9 -0
  34. mailpoet.php +2 -2
  35. readme.txt +9 -2
  36. vendor/autoload.php +1 -1
  37. vendor/composer/ClassLoader.php +5 -31
  38. vendor/composer/autoload_classmap.php +4 -0
  39. vendor/composer/autoload_real.php +8 -8
  40. vendor/composer/autoload_static.php +9 -5
  41. vendor/composer/installed.json +13 -13
  42. views/layout.html +1 -0
  43. views/premium.html +21 -20
  44. views/settings.html +13 -0
  45. views/settings/mta.html +25 -2
  46. views/settings/premium.html +28 -0
  47. views/update.html +9 -16
  48. views/welcome.html +3 -20
assets/css/{admin.06d5a0b9.css → admin.71690c62.css} RENAMED
@@ -1275,6 +1275,9 @@ a:focus {
1275
  .mailpoet_spaced_block {
1276
  margin: 1em 0;
1277
  }
 
 
 
1278
  .select2-container {
1279
  width: 25em !important;
1280
  }
@@ -3082,24 +3085,6 @@ textarea.parsley-error {
3082
  .mailpoet-about-wrap .feature-section.two-col h3 {
3083
  margin-top: 0;
3084
  }
3085
- .mailpoet-about-wrap .feature-section.one-col {
3086
- width: 700px;
3087
- margin: 0 auto;
3088
- text-align: center;
3089
- }
3090
- .mailpoet-about-wrap .feature-section.one-col > a.button {
3091
- margin-top: 2em;
3092
- }
3093
- .mailpoet-about-wrap .feature-section.one-col-left {
3094
- width: 700px;
3095
- margin: 0 auto;
3096
- }
3097
- .mailpoet-about-wrap .feature-section h2.mailpoet-feature-top {
3098
- margin: 50px auto;
3099
- }
3100
- .mailpoet-about-wrap .feature-section .lead-description ~ p {
3101
- margin-top: 3em;
3102
- }
3103
  .mailpoet-about-wrap .feature-section h4 {
3104
  margin: 1.4em 0 0.6em 0;
3105
  font-size: 1em;
@@ -3211,6 +3196,35 @@ textarea.parsley-error {
3211
  float: none !important;
3212
  }
3213
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3214
  #logger {
3215
  width: 100%;
3216
  height: 300px;
1275
  .mailpoet_spaced_block {
1276
  margin: 1em 0;
1277
  }
1278
+ .mailpoet_centered {
1279
+ text-align: center;
1280
+ }
1281
  .select2-container {
1282
  width: 25em !important;
1283
  }
3085
  .mailpoet-about-wrap .feature-section.two-col h3 {
3086
  margin-top: 0;
3087
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3088
  .mailpoet-about-wrap .feature-section h4 {
3089
  margin: 1.4em 0 0.6em 0;
3090
  font-size: 1em;
3196
  float: none !important;
3197
  }
3198
  }
3199
+ .mailpoet-about-wrap .videoWrapper {
3200
+ position: relative;
3201
+ padding-bottom: 56.25% /* 16:9 */;
3202
+ /*padding-top: 25px*/
3203
+ height: 0;
3204
+ }
3205
+ .mailpoet-about-wrap .videoWrapper iframe {
3206
+ position: absolute;
3207
+ top: 0;
3208
+ left: 0;
3209
+ width: 100%;
3210
+ height: 100%;
3211
+ }
3212
+ .mailpoet-about-wrap .mailpoet_video {
3213
+ border: 1px solid rgba(0,0,0,0.1);
3214
+ }
3215
+ .mailpoet-about-wrap #mailpoet-changelog ul {
3216
+ list-style: disc;
3217
+ padding-left: 20px;
3218
+ }
3219
+ .mailpoet-about-wrap h2.mailpoet-feature-top {
3220
+ margin: 50px auto;
3221
+ }
3222
+ .mailpoet-about-wrap a.button.go-to-plugin {
3223
+ margin-top: 2em;
3224
+ }
3225
+ .mailpoet-about-wrap p.top-space-triple {
3226
+ margin-top: 3em;
3227
+ }
3228
  #logger {
3229
  width: 100%;
3230
  height: 300px;
assets/css/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
  {
2
- "admin.css": "admin.06d5a0b9.css",
3
  "importExport.css": "importExport.b3745466.css",
4
  "newsletter_editor.css": "newsletter_editor.aace9f8f.css",
5
  "public.css": "public.cae357df.css",
1
  {
2
+ "admin.css": "admin.71690c62.css",
3
  "importExport.css": "importExport.b3745466.css",
4
  "newsletter_editor.css": "newsletter_editor.aace9f8f.css",
5
  "public.css": "public.cae357df.css",
assets/js/{admin.f15adcea.js → admin.607dbf77.js} RENAMED
@@ -9512,10 +9512,19 @@ webpackJsonp([0],[
9512
  }
9513
 
9514
  var fields = this.props.fields.map(function (field, i) {
 
 
 
 
 
 
 
 
 
9515
  return React.createElement(FormField, {
9516
  field: field,
9517
  item: _this3.getValues(),
9518
- onValueChange: _this3.handleValueChange,
9519
  key: 'field-' + i });
9520
  });
9521
 
@@ -28254,7 +28263,8 @@ webpackJsonp([0],[
28254
  _reactRouter.Link,
28255
  {
28256
  key: 'stats-' + newsletter.id,
28257
- to: params.link
 
28258
  },
28259
  content
28260
  ),
@@ -29428,12 +29438,10 @@ webpackJsonp([0],[
29428
  api_version: window.mailpoet_api_version,
29429
  endpoint: 'segments',
29430
  action: 'synchronize'
29431
- }).done(function (response) {
29432
  _mailpoet2['default'].Modal.loading(false);
29433
- if (response === true) {
29434
- _mailpoet2['default'].Notice.success(_mailpoet2['default'].I18n.t('listSynchronized').replace('%$1s', item.name));
29435
- refresh();
29436
- }
29437
  }).fail(function (response) {
29438
  _mailpoet2['default'].Modal.loading(false);
29439
  if (response.errors.length > 0) {
@@ -30007,6 +30015,14 @@ webpackJsonp([0],[
30007
 
30008
  // show "save settings" button
30009
  jQuery('.mailpoet_settings_submit').show();
 
 
 
 
 
 
 
 
30010
  }
30011
  }));
30012
 
9512
  }
9513
 
9514
  var fields = this.props.fields.map(function (field, i) {
9515
+ // Compose an onChange handler from the default and custom one
9516
+ var onValueChange = _this3.handleValueChange;
9517
+ if (field.onBeforeChange) {
9518
+ onValueChange = function (e) {
9519
+ field.onBeforeChange(e);
9520
+ return _this3.handleValueChange(e);
9521
+ };
9522
+ }
9523
+
9524
  return React.createElement(FormField, {
9525
  field: field,
9526
  item: _this3.getValues(),
9527
+ onValueChange: onValueChange,
9528
  key: 'field-' + i });
9529
  });
9530
 
28263
  _reactRouter.Link,
28264
  {
28265
  key: 'stats-' + newsletter.id,
28266
+ to: params.link,
28267
+ onClick: params.onClick || null
28268
  },
28269
  content
28270
  ),
29438
  api_version: window.mailpoet_api_version,
29439
  endpoint: 'segments',
29440
  action: 'synchronize'
29441
+ }).done(function () {
29442
  _mailpoet2['default'].Modal.loading(false);
29443
+ _mailpoet2['default'].Notice.success(_mailpoet2['default'].I18n.t('listSynchronized').replace('%$1s', item.name));
29444
+ refresh();
 
 
29445
  }).fail(function (response) {
29446
  _mailpoet2['default'].Modal.loading(false);
29447
  if (response.errors.length > 0) {
30015
 
30016
  // show "save settings" button
30017
  jQuery('.mailpoet_settings_submit').show();
30018
+
30019
+ MailPoet.trackEvent(
30020
+ 'User has clicked a tab in Settings',
30021
+ {
30022
+ 'MailPoet Free version': window.mailpoet_version,
30023
+ 'Tab ID': tab
30024
+ }
30025
+ );
30026
  }
30027
  }));
30028
 
assets/js/{admin_vendor.e019c409.js → admin_vendor.ea8adfbb.js} RENAMED
@@ -29118,6 +29118,7 @@ webpackJsonp([1],[
29118
  filters: this.state.filters,
29119
  filter: this.state.filter,
29120
  group: this.state.group,
 
29121
  onSelectFilter: this.handleFilter,
29122
  onEmptyTrash: this.handleEmptyTrash
29123
  }),
@@ -31357,6 +31358,9 @@ webpackJsonp([1],[
31357
  this.getAvailableFilters().map(function (filter, i) {
31358
  filters[_this.refs['filter-' + i].name] = _this.refs['filter-' + i].value;
31359
  });
 
 
 
31360
  return this.props.onSelectFilter(filters);
31361
  },
31362
  handleEmptyTrash: function handleEmptyTrash() {
29118
  filters: this.state.filters,
29119
  filter: this.state.filter,
29120
  group: this.state.group,
29121
+ onBeforeSelectFilter: this.props.onBeforeSelectFilter || null,
29122
  onSelectFilter: this.handleFilter,
29123
  onEmptyTrash: this.handleEmptyTrash
29124
  }),
31358
  this.getAvailableFilters().map(function (filter, i) {
31359
  filters[_this.refs['filter-' + i].name] = _this.refs['filter-' + i].value;
31360
  });
31361
+ if (this.props.onBeforeSelectFilter) {
31362
+ this.props.onBeforeSelectFilter(filters);
31363
+ }
31364
  return this.props.onSelectFilter(filters);
31365
  },
31366
  handleEmptyTrash: function handleEmptyTrash() {
assets/js/{form_editor.e0b22679.js → form_editor.81d8f2a0.js} RENAMED
@@ -7894,15 +7894,15 @@ webpackJsonp([2],{
7894
  {origin: "+move", bias: -1}
7895
  ); },
7896
  goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) {
7897
- var top = cm.charCoords(range.head, "div").top + 5;
7898
  return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")
7899
  }, sel_move); },
7900
  goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) {
7901
- var top = cm.charCoords(range.head, "div").top + 5;
7902
  return cm.coordsChar({left: 0, top: top}, "div")
7903
  }, sel_move); },
7904
  goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) {
7905
- var top = cm.charCoords(range.head, "div").top + 5;
7906
  var pos = cm.coordsChar({left: 0, top: top}, "div");
7907
  if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) }
7908
  return pos
@@ -9457,6 +9457,8 @@ webpackJsonp([2],{
9457
  }),
9458
 
9459
  operation: function(f){return runInOp(this, f)},
 
 
9460
 
9461
  refresh: methodOp(function() {
9462
  var oldHeight = this.display.cachedTextHeight;
@@ -10109,9 +10111,6 @@ webpackJsonp([2],{
10109
  this.pollingFast = false;
10110
  // Self-resetting timeout for the poller
10111
  this.polling = new Delayed();
10112
- // Tracks when input.reset has punted to just putting a short
10113
- // string into the textarea instead of the full selection.
10114
- this.inaccurateSelection = false;
10115
  // Used to work around IE issue with selection being forgotten when focus moves away from textarea
10116
  this.hasSelection = false;
10117
  this.composing = null;
@@ -10148,12 +10147,6 @@ webpackJsonp([2],{
10148
  if (signalDOMEvent(cm, e)) { return }
10149
  if (cm.somethingSelected()) {
10150
  setLastCopied({lineWise: false, text: cm.getSelections()});
10151
- if (input.inaccurateSelection) {
10152
- input.prevInput = "";
10153
- input.inaccurateSelection = false;
10154
- te.value = lastCopied.text.join("\n");
10155
- selectInput(te);
10156
- }
10157
  } else if (!cm.options.lineWiseCopyCut) {
10158
  return
10159
  } else {
@@ -10232,13 +10225,10 @@ webpackJsonp([2],{
10232
  // when not typing and nothing is selected)
10233
  TextareaInput.prototype.reset = function (typing) {
10234
  if (this.contextMenuPending || this.composing) { return }
10235
- var minimal, selected, cm = this.cm, doc = cm.doc;
10236
  if (cm.somethingSelected()) {
10237
  this.prevInput = "";
10238
- var range$$1 = doc.sel.primary();
10239
- minimal = hasCopyEvent &&
10240
- (range$$1.to().line - range$$1.from().line > 100 || (selected = cm.getSelection()).length > 1000);
10241
- var content = minimal ? "-" : selected || cm.getSelection();
10242
  this.textarea.value = content;
10243
  if (cm.state.focused) { selectInput(this.textarea); }
10244
  if (ie && ie_version >= 9) { this.hasSelection = content; }
@@ -10246,7 +10236,6 @@ webpackJsonp([2],{
10246
  this.prevInput = this.textarea.value = "";
10247
  if (ie && ie_version >= 9) { this.hasSelection = null; }
10248
  }
10249
- this.inaccurateSelection = minimal;
10250
  };
10251
 
10252
  TextareaInput.prototype.getField = function () { return this.textarea };
@@ -10597,7 +10586,7 @@ webpackJsonp([2],{
10597
 
10598
  addLegacyProps(CodeMirror$1);
10599
 
10600
- CodeMirror$1.version = "5.27.4";
10601
 
10602
  return CodeMirror$1;
10603
 
7894
  {origin: "+move", bias: -1}
7895
  ); },
7896
  goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) {
7897
+ var top = cm.cursorCoords(range.head, "div").top + 5;
7898
  return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")
7899
  }, sel_move); },
7900
  goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) {
7901
+ var top = cm.cursorCoords(range.head, "div").top + 5;
7902
  return cm.coordsChar({left: 0, top: top}, "div")
7903
  }, sel_move); },
7904
  goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) {
7905
+ var top = cm.cursorCoords(range.head, "div").top + 5;
7906
  var pos = cm.coordsChar({left: 0, top: top}, "div");
7907
  if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) }
7908
  return pos
9457
  }),
9458
 
9459
  operation: function(f){return runInOp(this, f)},
9460
+ startOperation: function(){return startOperation(this)},
9461
+ endOperation: function(){return endOperation(this)},
9462
 
9463
  refresh: methodOp(function() {
9464
  var oldHeight = this.display.cachedTextHeight;
10111
  this.pollingFast = false;
10112
  // Self-resetting timeout for the poller
10113
  this.polling = new Delayed();
 
 
 
10114
  // Used to work around IE issue with selection being forgotten when focus moves away from textarea
10115
  this.hasSelection = false;
10116
  this.composing = null;
10147
  if (signalDOMEvent(cm, e)) { return }
10148
  if (cm.somethingSelected()) {
10149
  setLastCopied({lineWise: false, text: cm.getSelections()});
 
 
 
 
 
 
10150
  } else if (!cm.options.lineWiseCopyCut) {
10151
  return
10152
  } else {
10225
  // when not typing and nothing is selected)
10226
  TextareaInput.prototype.reset = function (typing) {
10227
  if (this.contextMenuPending || this.composing) { return }
10228
+ var cm = this.cm;
10229
  if (cm.somethingSelected()) {
10230
  this.prevInput = "";
10231
+ var content = cm.getSelection();
 
 
 
10232
  this.textarea.value = content;
10233
  if (cm.state.focused) { selectInput(this.textarea); }
10234
  if (ie && ie_version >= 9) { this.hasSelection = content; }
10236
  this.prevInput = this.textarea.value = "";
10237
  if (ie && ie_version >= 9) { this.hasSelection = null; }
10238
  }
 
10239
  };
10240
 
10241
  TextareaInput.prototype.getField = function () { return this.textarea };
10586
 
10587
  addLegacyProps(CodeMirror$1);
10588
 
10589
+ CodeMirror$1.version = "5.28.0";
10590
 
10591
  return CodeMirror$1;
10592
 
assets/js/{mailpoet.0ebf4b66.js → mailpoet.5fb06233.js} RENAMED
File without changes
assets/js/manifest.json CHANGED
@@ -1,10 +1,10 @@
1
  {
2
  "mp2migrator.js": "mp2migrator.f7fa3be5.js",
3
- "public.js": "public.0e89cdab.js",
4
- "admin.js": "admin.f15adcea.js",
5
- "admin_vendor.js": "admin_vendor.e019c409.js",
6
- "form_editor.js": "form_editor.e0b22679.js",
7
- "mailpoet.js": "mailpoet.0ebf4b66.js",
8
- "newsletter_editor.js": "newsletter_editor.cec09cf2.js",
9
- "vendor.js": "vendor.6d57818a.js"
10
  }
1
  {
2
  "mp2migrator.js": "mp2migrator.f7fa3be5.js",
3
+ "public.js": "public.5a1e5874.js",
4
+ "admin.js": "admin.607dbf77.js",
5
+ "admin_vendor.js": "admin_vendor.ea8adfbb.js",
6
+ "form_editor.js": "form_editor.81d8f2a0.js",
7
+ "mailpoet.js": "mailpoet.5fb06233.js",
8
+ "newsletter_editor.js": "newsletter_editor.1d7ae8a6.js",
9
+ "vendor.js": "vendor.25e2ce6a.js"
10
  }
assets/js/{newsletter_editor.cec09cf2.js → newsletter_editor.1d7ae8a6.js} RENAMED
File without changes
assets/js/{public.0e89cdab.js → public.5a1e5874.js} RENAMED
File without changes
assets/js/{vendor.6d57818a.js → vendor.25e2ce6a.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":"f15adcea","1":"e019c409","2":"e0b22679","3":"0ebf4b66","4":"cec09cf2"}[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":"607dbf77","1":"ea8adfbb","2":"81d8f2a0","3":"5fb06233","4":"1d7ae8a6"}[chunkId] + ".chunk.js";
80
  /******/ head.appendChild(script);
81
  /******/ }
82
  /******/ };
lang/index.php CHANGED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php
2
+
3
+ // Silence is golden
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: 2017-07-18 10:51:01+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -365,8 +365,8 @@ msgstr ""
365
  msgid "Export"
366
  msgstr ""
367
 
368
- #: lib/Config/Menu.php:222 lib/Config/Menu.php:223 views/update.html:23
369
- #: views/welcome.html:32
370
  msgid "Welcome"
371
  msgstr ""
372
 
@@ -396,7 +396,7 @@ msgstr ""
396
  msgid "In any WordPress role"
397
  msgstr ""
398
 
399
- #: lib/Config/Menu.php:560 views/premium.html:39
400
  msgid "MailPoet"
401
  msgstr ""
402
 
@@ -1023,7 +1023,7 @@ msgstr ""
1023
  msgid "Daemon does not exist."
1024
  msgstr ""
1025
 
1026
- #: lib/Cron/Workers/SendingQueue/Tasks/Newsletter.php:95
1027
  msgid ""
1028
  "There was an error processing your newsletter during sending. If possible, "
1029
  "please contact us and report this issue."
@@ -1245,7 +1245,7 @@ msgstr ""
1245
  msgid "Trash"
1246
  msgstr ""
1247
 
1248
- #: lib/Models/Model.php:54 views/subscribers/importExport/import/step2.html:137
1249
  msgid "Another record already exists. Please specify a different \"%1$s\"."
1250
  msgstr ""
1251
 
@@ -1304,6 +1304,10 @@ msgstr ""
1304
  msgid "Not in a List"
1305
  msgstr ""
1306
 
 
 
 
 
1307
  #: lib/Models/Setting.php:48
1308
  msgid "Confirm your subscription to %1$s"
1309
  msgstr ""
@@ -1637,19 +1641,19 @@ msgstr ""
1637
  msgid "Accidentally unsubscribed?"
1638
  msgstr ""
1639
 
1640
- #: lib/Twig/Functions.php:88 views/settings/mta.html:1055
1641
  msgid "every minute"
1642
  msgstr ""
1643
 
1644
- #: lib/Twig/Functions.php:89 views/settings/mta.html:1056
1645
  msgid "every %1$d minutes"
1646
  msgstr ""
1647
 
1648
- #: lib/Twig/Functions.php:90 views/settings/mta.html:1057
1649
  msgid "every hour"
1650
  msgstr ""
1651
 
1652
- #: lib/Twig/Functions.php:91 views/settings/mta.html:1058
1653
  msgid "every %1$d hours"
1654
  msgstr ""
1655
 
@@ -1841,7 +1845,7 @@ msgstr ""
1841
  #: views/newsletter/templates/blocks/automatedLatestContent/settings.hbs:281
1842
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:79
1843
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:221
1844
- #: views/premium.html:54 views/settings/advanced.html:90
1845
  #: views/settings/advanced.html:130 views/settings/bounce.html:190
1846
  #: views/settings/mta.html:589 views/settings/signup.html:34
1847
  #: views/subscribers/importExport/export.html:33
@@ -1860,7 +1864,7 @@ msgstr ""
1860
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:139
1861
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:165
1862
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:227
1863
- #: views/premium.html:60 views/premium.html:61 views/settings/advanced.html:101
1864
  #: views/settings/advanced.html:141 views/settings/bounce.html:148
1865
  #: views/settings/bounce.html:179 views/settings/mta.html:546
1866
  #: views/settings/mta.html:600 views/settings/signup.html:46
@@ -2226,13 +2230,13 @@ msgstr ""
2226
  msgid "Visit MailPoet.com to purchase a key"
2227
  msgstr ""
2228
 
2229
- #: views/layout.html:59
2230
  msgid ""
2231
  "An error has happened while performing a request, the server has responded "
2232
  "with response code %d"
2233
  msgstr ""
2234
 
2235
- #: views/layout.html:83
2236
  msgid ""
2237
  "Want to give feedback to the MailPoet team? Contact us here. Please provide "
2238
  "as much information as possible!"
@@ -2656,7 +2660,7 @@ msgstr ""
2656
 
2657
  #: views/newsletter/templates/blocks/automatedLatestContent/settings.hbs:154
2658
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:111
2659
- #: views/premium.html:53
2660
  msgid "None"
2661
  msgstr ""
2662
 
@@ -3680,107 +3684,106 @@ msgstr ""
3680
  msgid "Sending has been resumed."
3681
  msgstr ""
3682
 
3683
- #: views/premium.html:12
3684
  msgid "What is MailPoet Premium?"
3685
  msgstr ""
3686
 
3687
- #: views/premium.html:14
3688
- msgid ""
3689
- "Detailed statistics, actionable insights, awesome deliverability, plus "
3690
- "great support!"
3691
  msgstr ""
3692
 
3693
- #: views/premium.html:18
3694
  msgid "Insightful Statistics"
3695
  msgstr ""
3696
 
3697
- #: views/premium.html:21
3698
  msgid ""
3699
  "Which links get the most clicks? Which subscribers opened your emails? With "
3700
  "MailPoet's stats program, it's easy to find out. Need even more details? "
3701
  "Integrating with Google Analytics is as easy as 1-2-3."
3702
  msgstr ""
3703
 
3704
- #: views/premium.html:31
3705
  msgid "Hello Inbox, Goodbye Spambox!"
3706
  msgstr ""
3707
 
3708
- #: views/premium.html:34
3709
  msgid ""
3710
- "The MailPoet Sending Service's delivery rate is over 98%: one of the best "
3711
- "in the industry! Our in-house sending service is constantly monitored, "
3712
- "tweaked, and improved to make sure that your emails arrive successfully."
 
3713
  msgstr ""
3714
 
3715
- #: views/premium.html:40
3716
  msgid "Web host"
3717
  msgstr ""
3718
 
3719
- #: views/premium.html:41
3720
  msgid "Third party"
3721
  msgstr ""
3722
 
3723
- #: views/premium.html:46
3724
  msgid "Speed"
3725
  msgstr ""
3726
 
3727
- #: views/premium.html:47
3728
  msgid "50,000 / hour"
3729
  msgstr ""
3730
 
3731
- #: views/premium.html:48
3732
  msgid "300 / hour"
3733
  msgstr ""
3734
 
3735
- #: views/premium.html:49
3736
  msgid "2,000 / hour"
3737
  msgstr ""
3738
 
3739
- #: views/premium.html:52
3740
  msgid "Daily email limits"
3741
  msgstr ""
3742
 
3743
- #: views/premium.html:55 views/premium.html:67 views/premium.html:73
3744
  msgid "Depends"
3745
  msgstr ""
3746
 
3747
- #: views/premium.html:58
3748
  msgid "Personal deliverability support"
3749
  msgstr ""
3750
 
3751
- #: views/premium.html:59
3752
  msgid "Yes!"
3753
  msgstr ""
3754
 
3755
- #: views/premium.html:64
3756
  msgid "SPF and DKIM Signatures"
3757
  msgstr ""
3758
 
3759
- #: views/premium.html:65
3760
  msgid "No need!"
3761
  msgstr ""
3762
 
3763
- #: views/premium.html:66
3764
  msgid "Update your DNS"
3765
  msgstr ""
3766
 
3767
- #: views/premium.html:70
3768
  msgid "Double opt-in"
3769
  msgstr ""
3770
 
3771
- #: views/premium.html:71
3772
  msgid "Enforced"
3773
  msgstr ""
3774
 
3775
- #: views/premium.html:72
3776
  msgid "Not enforced"
3777
  msgstr ""
3778
 
3779
- #: views/premium.html:81
3780
  msgid "View full comparison table"
3781
  msgstr ""
3782
 
3783
- #: views/premium.html:90
3784
  msgid ""
3785
  "Spammers are ineligible to use the MailPoet Sending Service. We reserve the "
3786
  "right to cancel any sending plan if we detect more than 5% hard bounces. "
@@ -3788,47 +3791,47 @@ msgid ""
3788
  "MailPoet[/link]."
3789
  msgstr ""
3790
 
3791
- #: views/premium.html:100
3792
  msgid "Welcome to My Newsletter!"
3793
  msgstr ""
3794
 
3795
- #: views/premium.html:106
3796
  msgid ""
3797
  "Want to send autoresponders and welcome emails to your subscribers? In "
3798
  "MailPoet, it’s easy as 1-2-3. Create welcome emails, educational courses, "
3799
  "and other automatic email newsletters."
3800
  msgstr ""
3801
 
3802
- #: views/premium.html:109
3803
  msgid "We’re Here to Help!"
3804
  msgstr ""
3805
 
3806
- #: views/premium.html:115
3807
  msgid ""
3808
  "We pride ourselves on giving nearly round-the-clock support. Our remote "
3809
  "team spans several continents, hemispheres, and time-zones! If you’ve got a "
3810
  "problem, we will help you fix it!"
3811
  msgstr ""
3812
 
3813
- #: views/premium.html:121
3814
  msgid "Get Started for Just $10"
3815
  msgstr ""
3816
 
3817
- #: views/premium.html:124
3818
  msgid ""
3819
- "Our plans start at just $10 per month. Each plan offers unlimited emails. "
3820
- "Pricing scales up with the size of your list."
3821
  msgstr ""
3822
 
3823
- #: views/premium.html:132
3824
  msgid "Purchase Now"
3825
  msgstr ""
3826
 
3827
- #: views/premium.html:136
3828
  msgid "Already a Premium customer? [link]Add your Key in the Settings page[/link]."
3829
  msgstr ""
3830
 
3831
- #: views/premium.html:140
3832
  msgid ""
3833
  "Don't need to use our sending service? Not a problem; we understand. You "
3834
  "can also [link]buy the Premium[/link] features separately. Prices start at "
@@ -4229,7 +4232,7 @@ msgid ""
4229
  "keep your lists clean."
4230
  msgstr ""
4231
 
4232
- #: views/settings/mta.html:98 views/welcome.html:53
4233
  msgid "Find out more"
4234
  msgstr ""
4235
 
@@ -4421,7 +4424,7 @@ msgstr ""
4421
  msgid "The email has been sent! Check your inbox."
4422
  msgstr ""
4423
 
4424
- #: views/settings/mta.html:768
4425
  msgid "You have selected an invalid sending method."
4426
  msgstr ""
4427
 
@@ -4563,7 +4566,7 @@ msgstr ""
4563
  msgid "Settings saved"
4564
  msgstr ""
4565
 
4566
- #: views/settings.html:140
4567
  msgid ""
4568
  "Are you sure? All of your MailPoet data will be permanently erased "
4569
  "(newsletters, statistics, subscribers, etc.)."
@@ -4963,128 +4966,128 @@ msgid ""
4963
  "add custom fields by editing the subscription form on the Forms page."
4964
  msgstr ""
4965
 
4966
- #: views/update.html:13 views/welcome.html:22
4967
  msgid "Greetings, humans."
4968
  msgstr ""
4969
 
4970
- #: views/update.html:15 views/welcome.html:24
4971
  msgid ""
4972
  "Thanks for using MailPoet! We really appreciate all of your love, "
4973
  "affection, [link]and (good) plugin reviews.[/link]"
4974
  msgstr ""
4975
 
4976
- #: views/update.html:24
4977
  msgid "What's New"
4978
  msgstr ""
4979
 
4980
- #: views/update.html:28
4981
  msgid "List of Changes"
4982
  msgstr ""
4983
 
4984
- #: views/update.html:39
4985
  msgid "See readme.txt for a changelog."
4986
  msgstr ""
4987
 
4988
- #: views/update.html:41
4989
  msgid "View all changes"
4990
  msgstr ""
4991
 
4992
- #: views/update.html:48
4993
  msgid "Do Your Part to Make MailPoet Better"
4994
  msgstr ""
4995
 
4996
- #: views/update.html:53
4997
  msgid "Yes, share my data anonymously."
4998
  msgstr ""
4999
 
5000
- #: views/update.html:56
5001
  msgid ""
5002
  "By sharing your data with us, you can help us understand what our users "
5003
  "like (and don't like)."
5004
  msgstr ""
5005
 
5006
- #: views/update.html:57
5007
  msgid "We use it to prioritize and develop new plugin features."
5008
  msgstr ""
5009
 
5010
- #: views/update.html:58
5011
  msgid ""
5012
  "Share your data to help shape the future of MailPoet! [link]Read "
5013
  "more.[/link]"
5014
  msgstr ""
5015
 
5016
- #: views/update.html:68
5017
  msgid "Care to Give Your Opinion?"
5018
  msgstr ""
5019
 
5020
- #: views/update.html:77 views/welcome.html:88
5021
  msgid "Awesome! Now, take me to MailPoet"
5022
  msgstr ""
5023
 
5024
- #: views/welcome.html:29
5025
  msgid "MailPoet Logo"
5026
  msgstr ""
5027
 
5028
- #: views/welcome.html:33
5029
  msgid "What's new"
5030
  msgstr ""
5031
 
5032
- #: views/welcome.html:45
5033
  msgid "Want to Make MailPoet Even Better?"
5034
  msgstr ""
5035
 
5036
- #: views/welcome.html:47
5037
  msgid "We Need Your Feedback!"
5038
  msgstr ""
5039
 
5040
- #: views/welcome.html:48
5041
  msgid ""
5042
  "As a beta tester, you have a very important job: to tell us what you think "
5043
  "about this new version. If you love it, tell us! If you hate it, let us "
5044
  "know! Any and all feedback is useful."
5045
  msgstr ""
5046
 
5047
- #: views/welcome.html:49
5048
  msgid ""
5049
  "To get in touch with us, simply click on the blue circle in the bottom "
5050
  "right corner of your screen. This button is visible on all MailPoet pages "
5051
  "on your WordPress dashboard."
5052
  msgstr ""
5053
 
5054
- #: views/welcome.html:52
5055
  msgid "Sharing is Caring"
5056
  msgstr ""
5057
 
5058
- #: views/welcome.html:53
5059
  msgid ""
5060
  "By sharing your data <i>anonymously</i> with us, you can help us understand "
5061
  "<i>how people use MailPoet</i> and <i>what sort of features they like and "
5062
  "don't like</i>."
5063
  msgstr ""
5064
 
5065
- #: views/welcome.html:58
5066
  msgid "Yes, I want to help!"
5067
  msgstr ""
5068
 
5069
- #: views/welcome.html:68 views/welcome.html:72
5070
  msgid "Subscribe To Our Newsletter"
5071
  msgstr ""
5072
 
5073
- #: views/welcome.html:69
5074
  msgid "About once a month, we send out a pretty cool newsletter ourselves."
5075
  msgstr ""
5076
 
5077
- #: views/welcome.html:70
5078
  msgid ""
5079
  "Sign up to get a curated selection of awesome links, tips and tricks for "
5080
  "using MailPoet, special offers, and important plugin updates!"
5081
  msgstr ""
5082
 
5083
- #: views/welcome.html:76
5084
  msgid "Learn the Ropes"
5085
  msgstr ""
5086
 
5087
- #: views/welcome.html:77
5088
  msgid ""
5089
  "New to MailPoet? Check out our brand new email course. Over the span of 3 "
5090
  "weeks, we'll teach you how to create and send your first MailPoet email "
4
  msgstr ""
5
  "Project-Id-Version: \n"
6
  "Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
7
+ "POT-Creation-Date: 2017-07-25 12:53:09+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
365
  msgid "Export"
366
  msgstr ""
367
 
368
+ #: lib/Config/Menu.php:222 lib/Config/Menu.php:223 views/update.html:16
369
+ #: views/welcome.html:16
370
  msgid "Welcome"
371
  msgstr ""
372
 
396
  msgid "In any WordPress role"
397
  msgstr ""
398
 
399
+ #: lib/Config/Menu.php:560 views/premium.html:41
400
  msgid "MailPoet"
401
  msgstr ""
402
 
1023
  msgid "Daemon does not exist."
1024
  msgstr ""
1025
 
1026
+ #: lib/Cron/Workers/SendingQueue/Tasks/Newsletter.php:168
1027
  msgid ""
1028
  "There was an error processing your newsletter during sending. If possible, "
1029
  "please contact us and report this issue."
1245
  msgid "Trash"
1246
  msgstr ""
1247
 
1248
+ #: lib/Models/Model.php:55 views/subscribers/importExport/import/step2.html:137
1249
  msgid "Another record already exists. Please specify a different \"%1$s\"."
1250
  msgstr ""
1251
 
1304
  msgid "Not in a List"
1305
  msgstr ""
1306
 
1307
+ #: lib/Models/SendingQueue.php:19
1308
+ msgid "Rendered newsletter body is invalid!"
1309
+ msgstr ""
1310
+
1311
  #: lib/Models/Setting.php:48
1312
  msgid "Confirm your subscription to %1$s"
1313
  msgstr ""
1641
  msgid "Accidentally unsubscribed?"
1642
  msgstr ""
1643
 
1644
+ #: lib/Twig/Functions.php:93 views/settings/mta.html:1075
1645
  msgid "every minute"
1646
  msgstr ""
1647
 
1648
+ #: lib/Twig/Functions.php:94 views/settings/mta.html:1076
1649
  msgid "every %1$d minutes"
1650
  msgstr ""
1651
 
1652
+ #: lib/Twig/Functions.php:95 views/settings/mta.html:1077
1653
  msgid "every hour"
1654
  msgstr ""
1655
 
1656
+ #: lib/Twig/Functions.php:96 views/settings/mta.html:1078
1657
  msgid "every %1$d hours"
1658
  msgstr ""
1659
 
1845
  #: views/newsletter/templates/blocks/automatedLatestContent/settings.hbs:281
1846
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:79
1847
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:221
1848
+ #: views/premium.html:56 views/settings/advanced.html:90
1849
  #: views/settings/advanced.html:130 views/settings/bounce.html:190
1850
  #: views/settings/mta.html:589 views/settings/signup.html:34
1851
  #: views/subscribers/importExport/export.html:33
1864
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:139
1865
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:165
1866
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:227
1867
+ #: views/premium.html:62 views/premium.html:63 views/settings/advanced.html:101
1868
  #: views/settings/advanced.html:141 views/settings/bounce.html:148
1869
  #: views/settings/bounce.html:179 views/settings/mta.html:546
1870
  #: views/settings/mta.html:600 views/settings/signup.html:46
2230
  msgid "Visit MailPoet.com to purchase a key"
2231
  msgstr ""
2232
 
2233
+ #: views/layout.html:60
2234
  msgid ""
2235
  "An error has happened while performing a request, the server has responded "
2236
  "with response code %d"
2237
  msgstr ""
2238
 
2239
+ #: views/layout.html:84
2240
  msgid ""
2241
  "Want to give feedback to the MailPoet team? Contact us here. Please provide "
2242
  "as much information as possible!"
2660
 
2661
  #: views/newsletter/templates/blocks/automatedLatestContent/settings.hbs:154
2662
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:111
2663
+ #: views/premium.html:55
2664
  msgid "None"
2665
  msgstr ""
2666
 
3684
  msgid "Sending has been resumed."
3685
  msgstr ""
3686
 
3687
+ #: views/premium.html:6
3688
  msgid "What is MailPoet Premium?"
3689
  msgstr ""
3690
 
3691
+ #: views/premium.html:8
3692
+ msgid "Check out the brief video below. Or, keep reading!"
 
 
3693
  msgstr ""
3694
 
3695
+ #: views/premium.html:20
3696
  msgid "Insightful Statistics"
3697
  msgstr ""
3698
 
3699
+ #: views/premium.html:23
3700
  msgid ""
3701
  "Which links get the most clicks? Which subscribers opened your emails? With "
3702
  "MailPoet's stats program, it's easy to find out. Need even more details? "
3703
  "Integrating with Google Analytics is as easy as 1-2-3."
3704
  msgstr ""
3705
 
3706
+ #: views/premium.html:33
3707
  msgid "Hello Inbox, Goodbye Spambox!"
3708
  msgstr ""
3709
 
3710
+ #: views/premium.html:36
3711
  msgid ""
3712
+ "Having issues with reaching your subscribers? Always ending up in the spam "
3713
+ "box? Don't panic! You're not alone - over a quarter of our plugin users "
3714
+ "have sending issues, usually because they are sending emails via their web "
3715
+ "host. Instead, try using the new MailPoet Sending Service."
3716
  msgstr ""
3717
 
3718
+ #: views/premium.html:42
3719
  msgid "Web host"
3720
  msgstr ""
3721
 
3722
+ #: views/premium.html:43
3723
  msgid "Third party"
3724
  msgstr ""
3725
 
3726
+ #: views/premium.html:48
3727
  msgid "Speed"
3728
  msgstr ""
3729
 
3730
+ #: views/premium.html:49
3731
  msgid "50,000 / hour"
3732
  msgstr ""
3733
 
3734
+ #: views/premium.html:50
3735
  msgid "300 / hour"
3736
  msgstr ""
3737
 
3738
+ #: views/premium.html:51
3739
  msgid "2,000 / hour"
3740
  msgstr ""
3741
 
3742
+ #: views/premium.html:54
3743
  msgid "Daily email limits"
3744
  msgstr ""
3745
 
3746
+ #: views/premium.html:57 views/premium.html:69 views/premium.html:75
3747
  msgid "Depends"
3748
  msgstr ""
3749
 
3750
+ #: views/premium.html:60
3751
  msgid "Personal deliverability support"
3752
  msgstr ""
3753
 
3754
+ #: views/premium.html:61
3755
  msgid "Yes!"
3756
  msgstr ""
3757
 
3758
+ #: views/premium.html:66
3759
  msgid "SPF and DKIM Signatures"
3760
  msgstr ""
3761
 
3762
+ #: views/premium.html:67
3763
  msgid "No need!"
3764
  msgstr ""
3765
 
3766
+ #: views/premium.html:68
3767
  msgid "Update your DNS"
3768
  msgstr ""
3769
 
3770
+ #: views/premium.html:72
3771
  msgid "Double opt-in"
3772
  msgstr ""
3773
 
3774
+ #: views/premium.html:73
3775
  msgid "Enforced"
3776
  msgstr ""
3777
 
3778
+ #: views/premium.html:74
3779
  msgid "Not enforced"
3780
  msgstr ""
3781
 
3782
+ #: views/premium.html:84
3783
  msgid "View full comparison table"
3784
  msgstr ""
3785
 
3786
+ #: views/premium.html:91
3787
  msgid ""
3788
  "Spammers are ineligible to use the MailPoet Sending Service. We reserve the "
3789
  "right to cancel any sending plan if we detect more than 5% hard bounces. "
3791
  "MailPoet[/link]."
3792
  msgstr ""
3793
 
3794
+ #: views/premium.html:101
3795
  msgid "Welcome to My Newsletter!"
3796
  msgstr ""
3797
 
3798
+ #: views/premium.html:107
3799
  msgid ""
3800
  "Want to send autoresponders and welcome emails to your subscribers? In "
3801
  "MailPoet, it’s easy as 1-2-3. Create welcome emails, educational courses, "
3802
  "and other automatic email newsletters."
3803
  msgstr ""
3804
 
3805
+ #: views/premium.html:110
3806
  msgid "We’re Here to Help!"
3807
  msgstr ""
3808
 
3809
+ #: views/premium.html:116
3810
  msgid ""
3811
  "We pride ourselves on giving nearly round-the-clock support. Our remote "
3812
  "team spans several continents, hemispheres, and time-zones! If you’ve got a "
3813
  "problem, we will help you fix it!"
3814
  msgstr ""
3815
 
3816
+ #: views/premium.html:122
3817
  msgid "Get Started for Just $10"
3818
  msgstr ""
3819
 
3820
+ #: views/premium.html:125
3821
  msgid ""
3822
+ "Our plans start at just $10 per month. Plus, if you pay annually, you’ll "
3823
+ "get two months for free!"
3824
  msgstr ""
3825
 
3826
+ #: views/premium.html:133
3827
  msgid "Purchase Now"
3828
  msgstr ""
3829
 
3830
+ #: views/premium.html:137
3831
  msgid "Already a Premium customer? [link]Add your Key in the Settings page[/link]."
3832
  msgstr ""
3833
 
3834
+ #: views/premium.html:141
3835
  msgid ""
3836
  "Don't need to use our sending service? Not a problem; we understand. You "
3837
  "can also [link]buy the Premium[/link] features separately. Prices start at "
4232
  "keep your lists clean."
4233
  msgstr ""
4234
 
4235
+ #: views/settings/mta.html:98 views/welcome.html:37
4236
  msgid "Find out more"
4237
  msgstr ""
4238
 
4424
  msgid "The email has been sent! Check your inbox."
4425
  msgstr ""
4426
 
4427
+ #: views/settings/mta.html:770
4428
  msgid "You have selected an invalid sending method."
4429
  msgstr ""
4430
 
4566
  msgid "Settings saved"
4567
  msgstr ""
4568
 
4569
+ #: views/settings.html:153
4570
  msgid ""
4571
  "Are you sure? All of your MailPoet data will be permanently erased "
4572
  "(newsletters, statistics, subscribers, etc.)."
4966
  "add custom fields by editing the subscription form on the Forms page."
4967
  msgstr ""
4968
 
4969
+ #: views/update.html:6 views/welcome.html:6
4970
  msgid "Greetings, humans."
4971
  msgstr ""
4972
 
4973
+ #: views/update.html:8 views/welcome.html:8
4974
  msgid ""
4975
  "Thanks for using MailPoet! We really appreciate all of your love, "
4976
  "affection, [link]and (good) plugin reviews.[/link]"
4977
  msgstr ""
4978
 
4979
+ #: views/update.html:17
4980
  msgid "What's New"
4981
  msgstr ""
4982
 
4983
+ #: views/update.html:21
4984
  msgid "List of Changes"
4985
  msgstr ""
4986
 
4987
+ #: views/update.html:32
4988
  msgid "See readme.txt for a changelog."
4989
  msgstr ""
4990
 
4991
+ #: views/update.html:34
4992
  msgid "View all changes"
4993
  msgstr ""
4994
 
4995
+ #: views/update.html:41
4996
  msgid "Do Your Part to Make MailPoet Better"
4997
  msgstr ""
4998
 
4999
+ #: views/update.html:46
5000
  msgid "Yes, share my data anonymously."
5001
  msgstr ""
5002
 
5003
+ #: views/update.html:49
5004
  msgid ""
5005
  "By sharing your data with us, you can help us understand what our users "
5006
  "like (and don't like)."
5007
  msgstr ""
5008
 
5009
+ #: views/update.html:50
5010
  msgid "We use it to prioritize and develop new plugin features."
5011
  msgstr ""
5012
 
5013
+ #: views/update.html:51
5014
  msgid ""
5015
  "Share your data to help shape the future of MailPoet! [link]Read "
5016
  "more.[/link]"
5017
  msgstr ""
5018
 
5019
+ #: views/update.html:61
5020
  msgid "Care to Give Your Opinion?"
5021
  msgstr ""
5022
 
5023
+ #: views/update.html:70 views/welcome.html:71
5024
  msgid "Awesome! Now, take me to MailPoet"
5025
  msgstr ""
5026
 
5027
+ #: views/welcome.html:13
5028
  msgid "MailPoet Logo"
5029
  msgstr ""
5030
 
5031
+ #: views/welcome.html:17
5032
  msgid "What's new"
5033
  msgstr ""
5034
 
5035
+ #: views/welcome.html:29
5036
  msgid "Want to Make MailPoet Even Better?"
5037
  msgstr ""
5038
 
5039
+ #: views/welcome.html:31
5040
  msgid "We Need Your Feedback!"
5041
  msgstr ""
5042
 
5043
+ #: views/welcome.html:32
5044
  msgid ""
5045
  "As a beta tester, you have a very important job: to tell us what you think "
5046
  "about this new version. If you love it, tell us! If you hate it, let us "
5047
  "know! Any and all feedback is useful."
5048
  msgstr ""
5049
 
5050
+ #: views/welcome.html:33
5051
  msgid ""
5052
  "To get in touch with us, simply click on the blue circle in the bottom "
5053
  "right corner of your screen. This button is visible on all MailPoet pages "
5054
  "on your WordPress dashboard."
5055
  msgstr ""
5056
 
5057
+ #: views/welcome.html:36
5058
  msgid "Sharing is Caring"
5059
  msgstr ""
5060
 
5061
+ #: views/welcome.html:37
5062
  msgid ""
5063
  "By sharing your data <i>anonymously</i> with us, you can help us understand "
5064
  "<i>how people use MailPoet</i> and <i>what sort of features they like and "
5065
  "don't like</i>."
5066
  msgstr ""
5067
 
5068
+ #: views/welcome.html:42
5069
  msgid "Yes, I want to help!"
5070
  msgstr ""
5071
 
5072
+ #: views/welcome.html:52 views/welcome.html:56
5073
  msgid "Subscribe To Our Newsletter"
5074
  msgstr ""
5075
 
5076
+ #: views/welcome.html:53
5077
  msgid "About once a month, we send out a pretty cool newsletter ourselves."
5078
  msgstr ""
5079
 
5080
+ #: views/welcome.html:54
5081
  msgid ""
5082
  "Sign up to get a curated selection of awesome links, tips and tricks for "
5083
  "using MailPoet, special offers, and important plugin updates!"
5084
  msgstr ""
5085
 
5086
+ #: views/welcome.html:60
5087
  msgid "Learn the Ropes"
5088
  msgstr ""
5089
 
5090
+ #: views/welcome.html:61
5091
  msgid ""
5092
  "New to MailPoet? Check out our brand new email course. Over the span of 3 "
5093
  "weeks, we'll teach you how to create and send your first MailPoet email "
lib/Analytics/Reporter.php CHANGED
@@ -2,31 +2,62 @@
2
  namespace MailPoet\Analytics;
3
 
4
  use MailPoet\Config\Installer;
 
 
5
  use MailPoet\Models\Newsletter;
6
  use MailPoet\Models\Setting;
7
  use MailPoet\Models\Subscriber;
 
8
 
9
  class Reporter {
10
 
11
  function getData() {
12
 
13
  $mta = Setting::getValue('mta', array());
14
- $premium_status = Installer::getPremiumStatus();
15
  $newsletters = Newsletter::getAnalytics();
 
 
 
16
 
17
 
18
  return array(
19
  'MailPoet Free version' => MAILPOET_VERSION,
20
  'MailPoet Premium version' => (defined('MAILPOET_PREMIUM_VERSION')) ? MAILPOET_PREMIUM_VERSION : 'N/A',
21
- 'Premium Plugin Installed' => $premium_status['premium_plugin_installed'],
22
- 'Premium Plugin Active' => $premium_status['premium_plugin_active'],
23
  'Total number of subscribers' => Subscriber::getTotalSubscribers(),
24
- 'Sending Method' => $mta['method'],
25
  'Date of plugin installation' => Setting::getValue('installed_at'),
 
 
 
 
 
 
 
 
 
 
26
  'Number of standard newsletters sent in last 3 months' => $newsletters['sent_newsletters'],
27
  'Number of active post notifications' => $newsletters['notifications_count'],
28
  'Number of active welcome emails' => $newsletters['welcome_newsletters_count'],
29
- 'Is WooCommerce plugin installed' => is_plugin_active("woocommerce/woocommerce.php"),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  );
31
  }
32
 
2
  namespace MailPoet\Analytics;
3
 
4
  use MailPoet\Config\Installer;
5
+ use MailPoet\Config\ServicesChecker;
6
+ use MailPoet\Cron\CronTrigger;
7
  use MailPoet\Models\Newsletter;
8
  use MailPoet\Models\Setting;
9
  use MailPoet\Models\Subscriber;
10
+ use MailPoet\Settings\Pages;
11
 
12
  class Reporter {
13
 
14
  function getData() {
15
 
16
  $mta = Setting::getValue('mta', array());
 
17
  $newsletters = Newsletter::getAnalytics();
18
+ $isCronTriggerMethodWP = Setting::getValue('cron_trigger.method') === CronTrigger::$available_methods['wordpress'];
19
+ $checker = new ServicesChecker();
20
+ $bounceAddress = Setting::getValue('bounce.address');
21
 
22
 
23
  return array(
24
  'MailPoet Free version' => MAILPOET_VERSION,
25
  'MailPoet Premium version' => (defined('MAILPOET_PREMIUM_VERSION')) ? MAILPOET_PREMIUM_VERSION : 'N/A',
 
 
26
  'Total number of subscribers' => Subscriber::getTotalSubscribers(),
27
+ 'Sending Method' => isset($mta['method']) ? $mta['method'] : null,
28
  'Date of plugin installation' => Setting::getValue('installed_at'),
29
+ 'Subscribe in comments' => (boolean)Setting::getValue('subscribe.on_comment.enabled', false),
30
+ 'Subscribe in registration form' => (boolean)Setting::getValue('subscribe.on_register.enabled', false),
31
+ 'Manage Subscription page > MailPoet page' => (boolean)Pages::isMailpoetPage(intval(Setting::getValue('subscription.pages.manage'))),
32
+ 'Unsubscribe page > MailPoet page' => (boolean)Pages::isMailpoetPage(intval(Setting::getValue('subscription.pages.unsubscribe'))),
33
+ 'Sign-up confirmation' => (boolean)Setting::getValue('signup_confirmation.enabled', false),
34
+ 'Sign-up confirmation: Confirmation page > MailPoet page' => (boolean)Pages::isMailpoetPage(intval(Setting::getValue('subscription.pages.confirmation'))),
35
+ 'Bounce email address' => !empty($bounceAddress),
36
+ 'Newsletter task scheduler (cron)' => $isCronTriggerMethodWP ? 'visitors' : 'script',
37
+ 'Open and click tracking' => (boolean)Setting::getValue('tracking.enabled', false),
38
+ 'Premium key valid' => $checker->isPremiumKeyValid(),
39
  'Number of standard newsletters sent in last 3 months' => $newsletters['sent_newsletters'],
40
  'Number of active post notifications' => $newsletters['notifications_count'],
41
  'Number of active welcome emails' => $newsletters['welcome_newsletters_count'],
42
+ 'Plugin > MailPoet Premium' => is_plugin_active('mailpoet-premium/mailpoet-premium.php'),
43
+ 'Plugin > bounce add-on' => is_plugin_active('mailpoet-bounce-handler/mailpoet-bounce-handler.php'),
44
+ 'Plugin > Bloom' => is_plugin_active('bloom-for-publishers/bloom.php'),
45
+ 'Plugin > WP Holler' => is_plugin_active('holler-box/holler-box.php'),
46
+ 'Plugin > WP-SMTP' => is_plugin_active('wp-mail-smtp/wp_mail_smtp.php'),
47
+ 'Plugin > WooCommerce' => is_plugin_active('woocommerce/woocommerce.php'),
48
+ 'Plugin > WooCommerce Subscription' => is_plugin_active('woocommerce-subscriptions/woocommerce-subscriptions.php'),
49
+ 'Plugin > WooCommerce Follow Up Emails' => is_plugin_active('woocommerce-follow-up-emails/woocommerce-follow-up-emails.php'),
50
+ 'Plugin > WooCommerce Email Customizer' => is_plugin_active('woocommerce-email-customizer/woocommerce-email-customizer.php'),
51
+ 'Plugin > WooCommerce Memberships' => is_plugin_active('woocommerce-memberships/woocommerce-memberships.php'),
52
+ 'Plugin > WooCommerce MailChimp' => is_plugin_active('woocommerce-mailchimp/woocommerce-mailchimp.php'),
53
+ 'Plugin > MailChimp for WooCommerce' => is_plugin_active('mailchimp-for-woocommerce/mailchimp-woocommerce.php'),
54
+ 'Plugin > The Event Calendar' => is_plugin_active('the-events-calendar/the-events-calendar.php'),
55
+ 'Plugin > Gravity Forms' => is_plugin_active('gravityforms/gravityforms.php'),
56
+ 'Plugin > Ninja Forms' => is_plugin_active('ninja-forms/ninja-forms.php'),
57
+ 'Plugin > WPForms' => is_plugin_active('wpforms-lite/wpforms.php'),
58
+ 'Plugin > Formidable Forms' => is_plugin_active('formidable/formidable.php'),
59
+ 'Plugin > Contact Form 7' => is_plugin_active('contact-form-7/wp-contact-form-7.php'),
60
+ 'Plugin > Easy Digital Downloads' => is_plugin_active('easy-digital-downloads/easy-digital-downloads.php'),
61
  );
62
  }
63
 
lib/Config/Database.php CHANGED
@@ -70,6 +70,7 @@ class Database {
70
  $subscriber_custom_field = Env::$db_prefix . 'subscriber_custom_field';
71
  $newsletter_segment = Env::$db_prefix . 'newsletter_segment';
72
  $scheduled_tasks = Env::$db_prefix . 'scheduled_tasks';
 
73
  $sending_queues = Env::$db_prefix . 'sending_queues';
74
  $newsletters = Env::$db_prefix . 'newsletters';
75
  $newsletter_templates = Env::$db_prefix . 'newsletter_templates';
@@ -92,6 +93,7 @@ class Database {
92
  define('MP_SUBSCRIBER_SEGMENT_TABLE', $subscriber_segment);
93
  define('MP_SUBSCRIBER_CUSTOM_FIELD_TABLE', $subscriber_custom_field);
94
  define('MP_SCHEDULED_TASKS_TABLE', $scheduled_tasks);
 
95
  define('MP_SENDING_QUEUES_TABLE', $sending_queues);
96
  define('MP_NEWSLETTERS_TABLE', $newsletters);
97
  define('MP_NEWSLETTER_TEMPLATES_TABLE', $newsletter_templates);
70
  $subscriber_custom_field = Env::$db_prefix . 'subscriber_custom_field';
71
  $newsletter_segment = Env::$db_prefix . 'newsletter_segment';
72
  $scheduled_tasks = Env::$db_prefix . 'scheduled_tasks';
73
+ $scheduled_task_subscribers = Env::$db_prefix . 'scheduled_task_subscribers';
74
  $sending_queues = Env::$db_prefix . 'sending_queues';
75
  $newsletters = Env::$db_prefix . 'newsletters';
76
  $newsletter_templates = Env::$db_prefix . 'newsletter_templates';
93
  define('MP_SUBSCRIBER_SEGMENT_TABLE', $subscriber_segment);
94
  define('MP_SUBSCRIBER_CUSTOM_FIELD_TABLE', $subscriber_custom_field);
95
  define('MP_SCHEDULED_TASKS_TABLE', $scheduled_tasks);
96
+ define('MP_SCHEDULED_TASK_SUBSCRIBERS_TABLE', $scheduled_task_subscribers);
97
  define('MP_SENDING_QUEUES_TABLE', $sending_queues);
98
  define('MP_NEWSLETTERS_TABLE', $newsletters);
99
  define('MP_NEWSLETTER_TEMPLATES_TABLE', $newsletter_templates);
lib/Config/Initializer.php CHANGED
@@ -13,6 +13,8 @@ require_once(ABSPATH . 'wp-admin/includes/plugin.php');
13
 
14
  class Initializer {
15
 
 
 
16
  protected $plugin_initialized = false;
17
 
18
  function __construct($params = array(
@@ -34,8 +36,7 @@ class Initializer {
34
  try {
35
  $this->setupDB();
36
  } catch(\Exception $e) {
37
- $this->handleFailedInitialization($e);
38
- return;
39
  }
40
 
41
  // activation function
@@ -236,11 +237,11 @@ class Initializer {
236
  $conflict_resolver->init();
237
  }
238
 
239
- function handleFailedInitialization($message) {
240
  // Check if we are able to add pages at this point
241
  if(function_exists('wp_get_current_user')) {
242
  Menu::addErrorPage();
243
  }
244
- return WPNotice::displayError($message);
245
  }
246
  }
13
 
14
  class Initializer {
15
 
16
+ const UNABLE_TO_CONNECT = '<strong>Mailpoet:</strong> Unable to connect to the database (the database is unable to open a file or folder), the connection is likely not configured correctly. Please read our <a href="http://beta.docs.mailpoet.com/article/200-solving-database-connection-issues">Knowledge Base article</a> for steps how to resolve it.';
17
+
18
  protected $plugin_initialized = false;
19
 
20
  function __construct($params = array(
36
  try {
37
  $this->setupDB();
38
  } catch(\Exception $e) {
39
+ return WPNotice::displayWarning(self::UNABLE_TO_CONNECT);
 
40
  }
41
 
42
  // activation function
237
  $conflict_resolver->init();
238
  }
239
 
240
+ function handleFailedInitialization($exception) {
241
  // Check if we are able to add pages at this point
242
  if(function_exists('wp_get_current_user')) {
243
  Menu::addErrorPage();
244
  }
245
+ return WPNotice::displayError($exception);
246
  }
247
  }
lib/Config/Migrator.php CHANGED
@@ -18,6 +18,7 @@ class Migrator {
18
  'settings',
19
  'custom_fields',
20
  'scheduled_tasks',
 
21
  'sending_queues',
22
  'subscribers',
23
  'subscriber_segment',
@@ -109,12 +110,8 @@ class Migrator {
109
  $attributes = array(
110
  'id mediumint(9) NOT NULL AUTO_INCREMENT,',
111
  'type varchar(90) NULL DEFAULT NULL,',
112
- 'subscribers longtext,',
113
  'status varchar(12) NULL DEFAULT NULL,',
114
  'priority mediumint(9) NOT NULL DEFAULT 0,',
115
- 'count_total mediumint(9) NOT NULL DEFAULT 0,',
116
- 'count_processed mediumint(9) NOT NULL DEFAULT 0,',
117
- 'count_to_process mediumint(9) NOT NULL DEFAULT 0,',
118
  'scheduled_at TIMESTAMP NULL,',
119
  'processed_at TIMESTAMP NULL,',
120
  'created_at TIMESTAMP NULL,',
@@ -125,6 +122,17 @@ class Migrator {
125
  return $this->sqlify(__FUNCTION__, $attributes);
126
  }
127
 
 
 
 
 
 
 
 
 
 
 
 
128
  function sendingQueues() {
129
  $attributes = array(
130
  'id mediumint(9) NOT NULL AUTO_INCREMENT,',
18
  'settings',
19
  'custom_fields',
20
  'scheduled_tasks',
21
+ 'scheduled_task_subscribers',
22
  'sending_queues',
23
  'subscribers',
24
  'subscriber_segment',
110
  $attributes = array(
111
  'id mediumint(9) NOT NULL AUTO_INCREMENT,',
112
  'type varchar(90) NULL DEFAULT NULL,',
 
113
  'status varchar(12) NULL DEFAULT NULL,',
114
  'priority mediumint(9) NOT NULL DEFAULT 0,',
 
 
 
115
  'scheduled_at TIMESTAMP NULL,',
116
  'processed_at TIMESTAMP NULL,',
117
  'created_at TIMESTAMP NULL,',
122
  return $this->sqlify(__FUNCTION__, $attributes);
123
  }
124
 
125
+ function scheduledTaskSubscribers() {
126
+ $attributes = array(
127
+ 'task_id mediumint(9) NOT NULL,',
128
+ 'subscriber_id mediumint(9) NOT NULL,',
129
+ 'processed int(1) NOT NULL,',
130
+ 'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
131
+ 'PRIMARY KEY (task_id, subscriber_id)',
132
+ );
133
+ return $this->sqlify(__FUNCTION__, $attributes);
134
+ }
135
+
136
  function sendingQueues() {
137
  $attributes = array(
138
  'id mediumint(9) NOT NULL AUTO_INCREMENT,',
lib/Cron/Workers/Bounce.php CHANGED
@@ -4,6 +4,10 @@ namespace MailPoet\Cron\Workers;
4
  use MailPoet\Cron\CronHelper;
5
  use MailPoet\Mailer\Mailer;
6
  use MailPoet\Models\ScheduledTask;
 
 
 
 
7
  use MailPoet\Models\Subscriber;
8
  use MailPoet\Services\Bridge;
9
  use MailPoet\Services\Bridge\API;
@@ -33,42 +37,25 @@ class Bounce extends SimpleWorker {
33
  }
34
 
35
  function prepareTask(ScheduledTask $task) {
36
- $subscribers = Subscriber::select('id')
37
- ->whereNull('deleted_at')
38
- ->whereIn('status', array(
39
- Subscriber::STATUS_SUBSCRIBED,
40
- Subscriber::STATUS_UNCONFIRMED
41
- ))
42
- ->findArray();
43
- $subscribers = Helpers::arrayColumn($subscribers, 'id');
44
-
45
- if(empty($subscribers)) {
46
  $task->delete();
47
  return false;
48
  }
49
 
50
- // update current task
51
- $task->subscribers = serialize(
52
- array(
53
- 'to_process' => $subscribers
54
- )
55
- );
56
- $task->count_total = $task->count_to_process = count($subscribers);
57
-
58
  return parent::prepareTask($task);
59
  }
60
 
61
  function processTask(ScheduledTask $task) {
62
- $task->subscribers = $task->getSubscribers();
63
- if(empty($task->subscribers['to_process'])) {
 
64
  $task->delete();
65
  return false;
66
  }
67
 
68
- $subscriber_batches = array_chunk(
69
- $task->subscribers['to_process'],
70
- self::BATCH_SIZE
71
- );
72
 
73
  foreach($subscriber_batches as $subscribers_to_process_ids) {
74
  // abort if execution limit is reached
@@ -82,7 +69,7 @@ class Bounce extends SimpleWorker {
82
 
83
  $this->processEmails($subscriber_emails);
84
 
85
- $task->updateProcessedSubscribers($subscribers_to_process_ids);
86
  }
87
 
88
  return true;
4
  use MailPoet\Cron\CronHelper;
5
  use MailPoet\Mailer\Mailer;
6
  use MailPoet\Models\ScheduledTask;
7
+ use MailPoet\Models\ScheduledTaskSubscriber;
8
+ use MailPoet\Tasks\Bounce as BounceTask;
9
+ use MailPoet\Tasks\Subscribers as TaskSubscribers;
10
+ use MailPoet\Tasks\Subscribers\BatchIterator;
11
  use MailPoet\Models\Subscriber;
12
  use MailPoet\Services\Bridge;
13
  use MailPoet\Services\Bridge\API;
37
  }
38
 
39
  function prepareTask(ScheduledTask $task) {
40
+ BounceTask::prepareSubscribers($task);
41
+
42
+ if(!ScheduledTaskSubscriber::getUnprocessedCount($task->id)) {
 
 
 
 
 
 
 
43
  $task->delete();
44
  return false;
45
  }
46
 
 
 
 
 
 
 
 
 
47
  return parent::prepareTask($task);
48
  }
49
 
50
  function processTask(ScheduledTask $task) {
51
+ $subscriber_batches = new BatchIterator($task->id, self::BATCH_SIZE);
52
+
53
+ if(count($subscriber_batches) === 0) {
54
  $task->delete();
55
  return false;
56
  }
57
 
58
+ $task_subscribers = new TaskSubscribers($task);
 
 
 
59
 
60
  foreach($subscriber_batches as $subscribers_to_process_ids) {
61
  // abort if execution limit is reached
69
 
70
  $this->processEmails($subscriber_emails);
71
 
72
+ $task_subscribers->updateProcessedSubscribers($subscribers_to_process_ids);
73
  }
74
 
75
  return true;
lib/Cron/Workers/SendingQueue/SendingQueue.php CHANGED
@@ -64,11 +64,11 @@ class SendingQueue {
64
  }
65
  // if some subscribers weren't found, remove them from the processing list
66
  if(count($found_subscribers_ids) !== count($subscribers_to_process_ids)) {
67
- $subscibers_to_remove = array_diff(
68
  $subscribers_to_process_ids,
69
  $found_subscribers_ids
70
  );
71
- $queue->removeNonexistentSubscribers($subscibers_to_remove);
72
  if(!count($queue->subscribers['to_process'])) {
73
  $this->newsletter_task->markNewsletterAsSent($newsletter, $queue);
74
  continue;
64
  }
65
  // if some subscribers weren't found, remove them from the processing list
66
  if(count($found_subscribers_ids) !== count($subscribers_to_process_ids)) {
67
+ $subscribers_to_remove = array_diff(
68
  $subscribers_to_process_ids,
69
  $found_subscribers_ids
70
  );
71
+ $queue->removeSubscribers($subscribers_to_remove);
72
  if(!count($queue->subscribers['to_process'])) {
73
  $this->newsletter_task->markNewsletterAsSent($newsletter, $queue);
74
  continue;
lib/Cron/Workers/SendingQueue/Tasks/Newsletter.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace MailPoet\Cron\Workers\SendingQueue\Tasks;
3
 
4
  use MailPoet\Cron\Workers\SendingQueue\Tasks\Links as LinksTask;
@@ -7,6 +8,7 @@ use MailPoet\Cron\Workers\SendingQueue\Tasks\Shortcodes as ShortcodesTask;
7
  use MailPoet\Mailer\MailerLog;
8
  use MailPoet\Models\Newsletter as NewsletterModel;
9
  use MailPoet\Models\NewsletterSegment as NewsletterSegmentModel;
 
10
  use MailPoet\Models\Setting;
11
  use MailPoet\Newsletter\Links\Links as NewsletterLinks;
12
  use MailPoet\Newsletter\Renderer\PostProcess\OpenTracking;
@@ -27,20 +29,24 @@ class Newsletter {
27
  // get existing active or sending newsletter
28
  $newsletter = $queue->newsletter()
29
  ->whereNull('deleted_at')
30
- ->whereAnyIs(array(
31
- array('status' => NewsletterModel::STATUS_ACTIVE),
32
- array('status' => NewsletterModel::STATUS_SENDING)
33
- ))
 
 
34
  ->findOne();
35
  if(!$newsletter) return false;
36
  // if this is a notification history, get existing active or sending parent newsletter
37
  if($newsletter->type == NewsletterModel::TYPE_NOTIFICATION_HISTORY) {
38
  $parent_newsletter = $newsletter->parent()
39
  ->whereNull('deleted_at')
40
- ->whereAnyIs(array(
41
- array('status' => NewsletterModel::STATUS_ACTIVE),
42
- array('status' => NewsletterModel::STATUS_SENDING)
43
- ))
 
 
44
  ->findOne();
45
  if(!$parent_newsletter) return false;
46
  }
@@ -50,7 +56,9 @@ class Newsletter {
50
  function preProcessNewsletter($newsletter, $queue) {
51
  // return the newsletter if it was previously rendered
52
  if(!is_null($queue->getNewsletterRenderedBody())) {
53
- return $newsletter;
 
 
54
  }
55
  // if tracking is enabled, do additional processing
56
  if($this->tracking_enabled) {
@@ -77,7 +85,7 @@ class Newsletter {
77
  // check if this is a post notification and if it contains posts
78
  $newsletter_contains_posts = strpos($rendered_newsletter['html'], 'data-post-id');
79
  if($newsletter->type === NewsletterModel::TYPE_NOTIFICATION_HISTORY &&
80
- !$newsletter_contains_posts
81
  ) {
82
  // delete notification history record since it will never be sent
83
  $newsletter->delete();
@@ -89,11 +97,15 @@ class Newsletter {
89
  $queue->newsletter_rendered_subject = Shortcodes::process($newsletter->subject, $newsletter, null, $queue);
90
  $queue->newsletter_rendered_body = $rendered_newsletter;
91
  $queue->save();
92
- if($queue->getErrors()) {
93
- return MailerLog::processError(
94
- 'queue_save',
95
- __('There was an error processing your newsletter during sending. If possible, please contact us and report this issue.')
96
- );
 
 
 
 
97
  }
98
  return $newsletter;
99
  }
@@ -149,4 +161,11 @@ class Newsletter {
149
  ->findArray();
150
  return Helpers::flattenArray($segments);
151
  }
 
 
 
 
 
 
 
152
  }
1
  <?php
2
+
3
  namespace MailPoet\Cron\Workers\SendingQueue\Tasks;
4
 
5
  use MailPoet\Cron\Workers\SendingQueue\Tasks\Links as LinksTask;
8
  use MailPoet\Mailer\MailerLog;
9
  use MailPoet\Models\Newsletter as NewsletterModel;
10
  use MailPoet\Models\NewsletterSegment as NewsletterSegmentModel;
11
+ use MailPoet\Models\SendingQueue as SendingQueueModel;
12
  use MailPoet\Models\Setting;
13
  use MailPoet\Newsletter\Links\Links as NewsletterLinks;
14
  use MailPoet\Newsletter\Renderer\PostProcess\OpenTracking;
29
  // get existing active or sending newsletter
30
  $newsletter = $queue->newsletter()
31
  ->whereNull('deleted_at')
32
+ ->whereAnyIs(
33
+ array(
34
+ array('status' => NewsletterModel::STATUS_ACTIVE),
35
+ array('status' => NewsletterModel::STATUS_SENDING)
36
+ )
37
+ )
38
  ->findOne();
39
  if(!$newsletter) return false;
40
  // if this is a notification history, get existing active or sending parent newsletter
41
  if($newsletter->type == NewsletterModel::TYPE_NOTIFICATION_HISTORY) {
42
  $parent_newsletter = $newsletter->parent()
43
  ->whereNull('deleted_at')
44
+ ->whereAnyIs(
45
+ array(
46
+ array('status' => NewsletterModel::STATUS_ACTIVE),
47
+ array('status' => NewsletterModel::STATUS_SENDING)
48
+ )
49
+ )
50
  ->findOne();
51
  if(!$parent_newsletter) return false;
52
  }
56
  function preProcessNewsletter($newsletter, $queue) {
57
  // return the newsletter if it was previously rendered
58
  if(!is_null($queue->getNewsletterRenderedBody())) {
59
+ return (!$queue->validate()) ?
60
+ $this->stopNewsletterPreProcessing() :
61
+ $newsletter;
62
  }
63
  // if tracking is enabled, do additional processing
64
  if($this->tracking_enabled) {
85
  // check if this is a post notification and if it contains posts
86
  $newsletter_contains_posts = strpos($rendered_newsletter['html'], 'data-post-id');
87
  if($newsletter->type === NewsletterModel::TYPE_NOTIFICATION_HISTORY &&
88
+ !$newsletter_contains_posts
89
  ) {
90
  // delete notification history record since it will never be sent
91
  $newsletter->delete();
97
  $queue->newsletter_rendered_subject = Shortcodes::process($newsletter->subject, $newsletter, null, $queue);
98
  $queue->newsletter_rendered_body = $rendered_newsletter;
99
  $queue->save();
100
+ // catch DB errors
101
+ $queue_errors = $queue->getErrors();
102
+ if(!$queue_errors) {
103
+ // verify that the rendered body was successfully saved
104
+ $queue = SendingQueueModel::findOne($queue->id);
105
+ $queue_errors = ($queue->validate() !== true);
106
+ }
107
+ if($queue_errors) {
108
+ $this->stopNewsletterPreProcessing();
109
  }
110
  return $newsletter;
111
  }
161
  ->findArray();
162
  return Helpers::flattenArray($segments);
163
  }
164
+
165
+ function stopNewsletterPreProcessing() {
166
+ MailerLog::processError(
167
+ 'queue_save',
168
+ __('There was an error processing your newsletter during sending. If possible, please contact us and report this issue.')
169
+ );
170
+ }
171
  }
lib/Models/Model.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace MailPoet\Models;
3
 
4
  if(!defined('ABSPATH')) exit;
@@ -78,14 +79,12 @@ class Model extends \Sudzy\ValidModel {
78
 
79
  static function bulkTrash($orm) {
80
  $model = get_called_class();
81
- $count = self::bulkAction($orm, function($ids) use($model) {
82
  $model::rawExecute(join(' ', array(
83
- 'UPDATE `'.$model::$_table.'`',
84
- 'SET `deleted_at` = NOW()',
85
- 'WHERE `id` IN ('.rtrim(str_repeat('?,', count($ids)), ',').')'
86
- )),
87
- $ids
88
- );
89
  });
90
 
91
  return array('count' => $count);
@@ -93,7 +92,7 @@ class Model extends \Sudzy\ValidModel {
93
 
94
  static function bulkDelete($orm) {
95
  $model = get_called_class();
96
- $count = self::bulkAction($orm, function($ids) use($model) {
97
  $model::whereIn('id', $ids)->deleteMany();
98
  });
99
 
@@ -106,14 +105,12 @@ class Model extends \Sudzy\ValidModel {
106
 
107
  static function bulkRestore($orm) {
108
  $model = get_called_class();
109
- $count = self::bulkAction($orm, function($ids) use($model) {
110
  $model::rawExecute(join(' ', array(
111
- 'UPDATE `'.$model::$_table.'`',
112
- 'SET `deleted_at` = NULL',
113
- 'WHERE `id` IN ('.rtrim(str_repeat('?,', count($ids)), ',').')'
114
- )),
115
- $ids
116
- );
117
  });
118
 
119
  return array('count' => $count);
@@ -124,7 +121,7 @@ class Model extends \Sudzy\ValidModel {
124
 
125
  if($total === 0) return false;
126
 
127
- $rows = $orm->select(static::$_table.'.id')
128
  ->offset(null)
129
  ->limit(null)
130
  ->findArray();
@@ -138,7 +135,8 @@ class Model extends \Sudzy\ValidModel {
138
  }
139
 
140
  // get number of affected rows
141
- return $orm->get_last_statement()->rowCount();
 
142
  }
143
 
144
  function duplicate($data = array()) {
@@ -146,7 +144,7 @@ class Model extends \Sudzy\ValidModel {
146
  $model_data = array_merge($this->asArray(), $data);
147
  unset($model_data['id']);
148
 
149
- $duplicate = $model::create();
150
  $duplicate->hydrate($model_data);
151
  $duplicate->set_expr('created_at', 'NOW()');
152
  $duplicate->set_expr('updated_at', 'NOW()');
@@ -171,10 +169,10 @@ class Model extends \Sudzy\ValidModel {
171
  }
172
 
173
  /**
174
- * PHP 5.3 fix for incorrectly returned model results when using asArray() function.
175
  * Jira reference: https://goo.gl/UZaMj5
176
  * TODO: remove after phasing out PHP 5.3 support
177
- */
178
  function asArray() {
179
  return call_user_func_array('parent::as_array', func_get_args());
180
  }
@@ -185,8 +183,17 @@ class Model extends \Sudzy\ValidModel {
185
  public static function __callStatic($method, $parameters) {
186
  try {
187
  return parent::__callStatic($method, $parameters);
188
- } catch (\PDOException $e) {
189
  throw new \Exception($e->getMessage());
190
  }
191
  }
192
- }
 
 
 
 
 
 
 
 
 
1
  <?php
2
+
3
  namespace MailPoet\Models;
4
 
5
  if(!defined('ABSPATH')) exit;
79
 
80
  static function bulkTrash($orm) {
81
  $model = get_called_class();
82
+ $count = self::bulkAction($orm, function($ids) use ($model) {
83
  $model::rawExecute(join(' ', array(
84
+ 'UPDATE `' . $model::$_table . '`',
85
+ 'SET `deleted_at` = NOW()',
86
+ 'WHERE `id` IN (' . rtrim(str_repeat('?,', count($ids)), ',') . ')'
87
+ )), $ids);
 
 
88
  });
89
 
90
  return array('count' => $count);
92
 
93
  static function bulkDelete($orm) {
94
  $model = get_called_class();
95
+ $count = self::bulkAction($orm, function($ids) use ($model) {
96
  $model::whereIn('id', $ids)->deleteMany();
97
  });
98
 
105
 
106
  static function bulkRestore($orm) {
107
  $model = get_called_class();
108
+ $count = self::bulkAction($orm, function($ids) use ($model) {
109
  $model::rawExecute(join(' ', array(
110
+ 'UPDATE `' . $model::$_table . '`',
111
+ 'SET `deleted_at` = NULL',
112
+ 'WHERE `id` IN (' . rtrim(str_repeat('?,', count($ids)), ',') . ')'
113
+ )), $ids);
 
 
114
  });
115
 
116
  return array('count' => $count);
121
 
122
  if($total === 0) return false;
123
 
124
+ $rows = $orm->select(static::$_table . '.id')
125
  ->offset(null)
126
  ->limit(null)
127
  ->findArray();
135
  }
136
 
137
  // get number of affected rows
138
+ return $orm->get_last_statement()
139
+ ->rowCount();
140
  }
141
 
142
  function duplicate($data = array()) {
144
  $model_data = array_merge($this->asArray(), $data);
145
  unset($model_data['id']);
146
 
147
+ $duplicate = $model::create();
148
  $duplicate->hydrate($model_data);
149
  $duplicate->set_expr('created_at', 'NOW()');
150
  $duplicate->set_expr('updated_at', 'NOW()');
169
  }
170
 
171
  /**
172
+ * PHP 5.3 fix for incorrectly returned model results when using asArray() function.
173
  * Jira reference: https://goo.gl/UZaMj5
174
  * TODO: remove after phasing out PHP 5.3 support
175
+ */
176
  function asArray() {
177
  return call_user_func_array('parent::as_array', func_get_args());
178
  }
183
  public static function __callStatic($method, $parameters) {
184
  try {
185
  return parent::__callStatic($method, $parameters);
186
+ } catch(\PDOException $e) {
187
  throw new \Exception($e->getMessage());
188
  }
189
  }
190
+
191
+ public function validate() {
192
+ $success = true;
193
+ foreach(array_keys($this->_validations) as $field) {
194
+ $success = $success && $this->validateField($field, $this->$field);
195
+ }
196
+ $this->setError($this->getValidationErrors());
197
+ return $success;
198
+ }
199
+ }
lib/Models/ModelValidator.php CHANGED
@@ -10,7 +10,8 @@ class ModelValidator extends \Sudzy\Engine {
10
  function __construct() {
11
  parent::__construct();
12
  $this->validators = array(
13
- 'validEmail' => 'validateEmail'
 
14
  );
15
  $this->setupValidators();
16
  }
@@ -27,4 +28,11 @@ class ModelValidator extends \Sudzy\Engine {
27
  function validateEmail($email) {
28
  return is_email($email) !== false;
29
  }
30
- }
 
 
 
 
 
 
 
10
  function __construct() {
11
  parent::__construct();
12
  $this->validators = array(
13
+ 'validEmail' => 'validateEmail',
14
+ 'validRenderedNewsletterBody' => 'validateRenderedNewsletterBody'
15
  );
16
  $this->setupValidators();
17
  }
28
  function validateEmail($email) {
29
  return is_email($email) !== false;
30
  }
31
+
32
+ function validateRenderedNewsletterBody($newsletter_body) {
33
+ $newsletter_body = (!is_serialized($newsletter_body)) ?
34
+ $newsletter_body :
35
+ unserialize($newsletter_body);
36
+ return (is_null($newsletter_body) || (is_array($newsletter_body) && !empty($newsletter_body['html']) && !empty($newsletter_body['text'])));
37
+ }
38
+ }
lib/Models/ScheduledTask.php CHANGED
@@ -12,85 +12,18 @@ class ScheduledTask extends Model {
12
  const PRIORITY_LOW = 10;
13
 
14
  function complete() {
 
15
  $this->set('status', self::STATUS_COMPLETED);
16
  $this->save();
17
  return ($this->getErrors() === false && $this->id() > 0);
18
  }
19
 
20
  function save() {
21
- if(!is_serialized($this->subscribers)) {
22
- $this->set('subscribers', serialize($this->subscribers));
23
- }
24
  // set the default priority to medium
25
  if(!$this->priority) {
26
  $this->priority = self::PRIORITY_MEDIUM;
27
  }
28
  parent::save();
29
- $this->subscribers = $this->getSubscribers();
30
  return $this;
31
  }
32
-
33
- function getSubscribers() {
34
- if(!is_serialized($this->subscribers)) {
35
- return $this->subscribers;
36
- }
37
- $subscribers = unserialize($this->subscribers);
38
- if(empty($subscribers['processed'])) {
39
- $subscribers['processed'] = array();
40
- }
41
- return $subscribers;
42
- }
43
-
44
- function isSubscriberProcessed($subscriber_id) {
45
- $subscribers = $this->getSubscribers();
46
- return in_array($subscriber_id, $subscribers['processed']);
47
- }
48
-
49
- function asArray() {
50
- $model = parent::asArray();
51
- $model['subscribers'] = (is_serialized($this->subscribers))
52
- ? unserialize($this->subscribers)
53
- : $this->subscribers;
54
- return $model;
55
- }
56
-
57
- function removeNonexistentSubscribers($subscribers_to_remove) {
58
- $subscribers = $this->getSubscribers();
59
- $subscribers['to_process'] = array_values(
60
- array_diff(
61
- $subscribers['to_process'],
62
- $subscribers_to_remove
63
- )
64
- );
65
- $this->subscribers = $subscribers;
66
- $this->updateCount();
67
- }
68
-
69
- function updateProcessedSubscribers($processed_subscribers) {
70
- $subscribers = $this->getSubscribers();
71
- $subscribers['processed'] = array_merge(
72
- $subscribers['processed'],
73
- $processed_subscribers
74
- );
75
- $subscribers['to_process'] = array_values(
76
- array_diff(
77
- $subscribers['to_process'],
78
- $processed_subscribers
79
- )
80
- );
81
- $this->subscribers = $subscribers;
82
- $this->updateCount();
83
- }
84
-
85
- function updateCount() {
86
- $this->subscribers = $this->getSubscribers();
87
- $this->count_processed = count($this->subscribers['processed']);
88
- $this->count_to_process = count($this->subscribers['to_process']);
89
- $this->count_total = $this->count_processed + $this->count_to_process;
90
- if(!$this->count_to_process) {
91
- $this->processed_at = current_time('mysql');
92
- $this->status = self::STATUS_COMPLETED;
93
- }
94
- return $this->save();
95
- }
96
- }
12
  const PRIORITY_LOW = 10;
13
 
14
  function complete() {
15
+ $this->processed_at = current_time('mysql');
16
  $this->set('status', self::STATUS_COMPLETED);
17
  $this->save();
18
  return ($this->getErrors() === false && $this->id() > 0);
19
  }
20
 
21
  function save() {
 
 
 
22
  // set the default priority to medium
23
  if(!$this->priority) {
24
  $this->priority = self::PRIORITY_MEDIUM;
25
  }
26
  parent::save();
 
27
  return $this;
28
  }
29
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/Models/ScheduledTaskSubscriber.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace MailPoet\Models;
3
+
4
+ if(!defined('ABSPATH')) exit;
5
+
6
+ class ScheduledTaskSubscriber extends Model {
7
+ const STATUS_UNPROCESSED = 0;
8
+ const STATUS_PROCESSED = 1;
9
+
10
+ public static $_table = MP_SCHEDULED_TASK_SUBSCRIBERS_TABLE;
11
+ public static $_id_column = array('task_id', 'subscriber_id');
12
+
13
+ static function createOrUpdate($data = array()) {
14
+ if(!is_array($data) || empty($data['task_id']) || empty($data['subscriber_id'])) return;
15
+
16
+ $task_subscriber = self::where('subscriber_id', $data['subscriber_id'])
17
+ ->where('task_id', $data['task_id'])
18
+ ->findOne();
19
+
20
+ if(empty($task_subscriber)) $task_subscriber = self::create();
21
+
22
+ $task_subscriber->task_id = $data['task_id'];
23
+ $task_subscriber->subscriber_id = $data['subscriber_id'];
24
+ $task_subscriber->processed = !empty($data['processed']) ? self::STATUS_PROCESSED : self::STATUS_UNPROCESSED;
25
+ $task_subscriber->save();
26
+
27
+ return $task_subscriber;
28
+ }
29
+
30
+ static function addSubscribers($task_id, array $subscriber_ids) {
31
+ foreach($subscriber_ids as $subscriber_id) {
32
+ self::createOrUpdate(array(
33
+ 'task_id' => $task_id,
34
+ 'subscriber_id' => $subscriber_id
35
+ ));
36
+ }
37
+ }
38
+
39
+ static function getUnprocessedCount($task_id) {
40
+ return self::getCount($task_id, self::STATUS_UNPROCESSED);
41
+ }
42
+
43
+ static function getProcessedCount($task_id) {
44
+ return self::getCount($task_id, self::STATUS_PROCESSED);
45
+ }
46
+
47
+ static function getTotalCount($task_id) {
48
+ return self::getCount($task_id);
49
+ }
50
+
51
+ private static function getCount($task_id, $processed = null) {
52
+ $orm = self::where('task_id', $task_id);
53
+ if(!is_null($processed)) {
54
+ $orm->where('processed', $processed);
55
+ }
56
+ return $orm->count();
57
+ }
58
+ }
lib/Models/SendingQueue.php CHANGED
@@ -12,6 +12,14 @@ class SendingQueue extends Model {
12
  const PRIORITY_MEDIUM = 5;
13
  const PRIORITY_LOW = 10;
14
 
 
 
 
 
 
 
 
 
15
  function newsletter() {
16
  return $this->has_one(__NAMESPACE__ . '\Newsletter', 'id', 'newsletter_id');
17
  }
@@ -43,10 +51,10 @@ class SendingQueue extends Model {
43
  }
44
 
45
  function save() {
46
- if(!is_serialized($this->subscribers)) {
47
  $this->set('subscribers', serialize($this->subscribers));
48
  }
49
- if(!is_serialized($this->newsletter_rendered_body)) {
50
  $this->set('newsletter_rendered_body', serialize($this->newsletter_rendered_body));
51
  }
52
  // set the default priority to medium
@@ -86,13 +94,12 @@ class SendingQueue extends Model {
86
 
87
  function asArray() {
88
  $model = parent::asArray();
89
- $model['subscribers'] = (is_serialized($this->subscribers))
90
- ? unserialize($this->subscribers)
91
- : $this->subscribers;
92
  return $model;
93
  }
94
 
95
- function removeNonexistentSubscribers($subscribers_to_remove) {
96
  $subscribers = $this->getSubscribers();
97
  $subscribers['to_process'] = array_values(
98
  array_diff(
12
  const PRIORITY_MEDIUM = 5;
13
  const PRIORITY_LOW = 10;
14
 
15
+ function __construct() {
16
+ parent::__construct();
17
+
18
+ $this->addValidations('newsletter_rendered_body', array(
19
+ 'validRenderedNewsletterBody' => __('Rendered newsletter body is invalid!', 'mailpoet')
20
+ ));
21
+ }
22
+
23
  function newsletter() {
24
  return $this->has_one(__NAMESPACE__ . '\Newsletter', 'id', 'newsletter_id');
25
  }
51
  }
52
 
53
  function save() {
54
+ if(!is_serialized($this->subscribers) && !is_null($this->subscribers)) {
55
  $this->set('subscribers', serialize($this->subscribers));
56
  }
57
+ if(!is_serialized($this->newsletter_rendered_body) && !is_null($this->newsletter_rendered_body)) {
58
  $this->set('newsletter_rendered_body', serialize($this->newsletter_rendered_body));
59
  }
60
  // set the default priority to medium
94
 
95
  function asArray() {
96
  $model = parent::asArray();
97
+ $model['subscribers'] = $this->getSubscribers();
98
+ $model['newsletter_rendered_body'] = $this->getNewsletterRenderedBody();
 
99
  return $model;
100
  }
101
 
102
+ function removeSubscribers($subscribers_to_remove) {
103
  $subscribers = $this->getSubscribers();
104
  $subscribers['to_process'] = array_values(
105
  array_diff(
lib/Newsletter/Shortcodes/ShortcodesHelper.php CHANGED
@@ -118,7 +118,7 @@ class ShortcodesHelper {
118
  return array_map(function ($custom_field) {
119
  return array(
120
  'text' => $custom_field->name,
121
- 'shortcode' => 'subscriber:cf_' . $custom_field->id
122
  );
123
  }, $custom_fields);
124
  }
118
  return array_map(function ($custom_field) {
119
  return array(
120
  'text' => $custom_field->name,
121
+ 'shortcode' => '[subscriber:cf_' . $custom_field->id . ']'
122
  );
123
  }, $custom_fields);
124
  }
lib/Segments/WP.php CHANGED
@@ -26,13 +26,9 @@ class WP {
26
  case 'deleted_user':
27
  case 'remove_user_from_blog':
28
  if($subscriber !== false) {
29
- // unlink subscriber to wp user
30
- $subscriber->setExpr('wp_user_id', 'NULL')->save();
31
-
32
- // delete subscription to wp segment
33
- SubscriberSegment::where('subscriber_id', $subscriber->id)
34
- ->where('segment_id', $wp_segment->id)
35
- ->deleteMany();
36
  }
37
  break;
38
  case 'profile_update':
@@ -97,6 +93,14 @@ class WP {
97
  static::synchronizeUser($wp_user_id);
98
  }
99
 
 
 
 
 
 
 
 
 
100
  return true;
101
  }
102
  }
26
  case 'deleted_user':
27
  case 'remove_user_from_blog':
28
  if($subscriber !== false) {
29
+ // unlink subscriber from wp user and delete
30
+ $subscriber->set('wp_user_id', null);
31
+ $subscriber->delete();
 
 
 
 
32
  }
33
  break;
34
  case 'profile_update':
93
  static::synchronizeUser($wp_user_id);
94
  }
95
 
96
+ // remove orphaned wp segment subscribers (not having a matching wp user id),
97
+ // e.g. if wp users were deleted directly from the database
98
+ $wp_segment->subscribers()
99
+ ->whereNotIn('wp_user_id', $wp_users)
100
+ ->findResultSet()
101
+ ->set('wp_user_id', null)
102
+ ->delete();
103
+
104
  return true;
105
  }
106
  }
lib/Settings/Pages.php CHANGED
@@ -48,6 +48,21 @@ class Pages {
48
  ));
49
  }
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  static function getAll() {
52
  $all_pages = array_merge(
53
  static::getMailPoetPages(),
48
  ));
49
  }
50
 
51
+ /**
52
+ * @param int $id
53
+ *
54
+ * @return bool
55
+ */
56
+ static function isMailpoetPage($id) {
57
+ $mailpoetPages = static::getMailPoetPages();
58
+ foreach($mailpoetPages as $mailpoetPage) {
59
+ if($mailpoetPage->ID === $id) {
60
+ return true;
61
+ }
62
+ }
63
+ return false;
64
+ }
65
+
66
  static function getAll() {
67
  $all_pages = array_merge(
68
  static::getMailPoetPages(),
lib/Tasks/Bounce.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace MailPoet\Tasks;
3
+
4
+ use MailPoet\Models\ScheduledTask;
5
+ use MailPoet\Models\ScheduledTaskSubscriber;
6
+ use MailPoet\Models\Subscriber;
7
+
8
+ if(!defined('ABSPATH')) exit;
9
+
10
+ class Bounce {
11
+ static function prepareSubscribers(ScheduledTask $task) {
12
+ // Prepare subscribers on the DB side for performance reasons
13
+ Subscriber::rawExecute(
14
+ 'INSERT INTO ' . MP_SCHEDULED_TASK_SUBSCRIBERS_TABLE . '
15
+ (task_id, subscriber_id, processed)
16
+ SELECT ? as task_id, s.`id` as subscriber_id, ? as processed
17
+ FROM ' . MP_SUBSCRIBERS_TABLE . ' s
18
+ WHERE s.`deleted_at` IS NULL
19
+ AND s.`status` IN (?, ?)',
20
+ array(
21
+ $task->id,
22
+ ScheduledTaskSubscriber::STATUS_UNPROCESSED,
23
+ Subscriber::STATUS_SUBSCRIBED,
24
+ Subscriber::STATUS_UNCONFIRMED
25
+ )
26
+ );
27
+ }
28
+ }
lib/Tasks/Subscribers.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace MailPoet\Tasks;
3
+
4
+ use MailPoet\Models\ScheduledTask;
5
+ use MailPoet\Models\ScheduledTaskSubscriber;
6
+
7
+ if(!defined('ABSPATH')) exit;
8
+
9
+ class Subscribers {
10
+ private $task;
11
+
12
+ public function __construct(ScheduledTask $task) {
13
+ $this->task = $task;
14
+ }
15
+
16
+ function getSubscribers() {
17
+ return ScheduledTaskSubscriber::where('task_id', $this->task->id);
18
+ }
19
+
20
+ function isSubscriberProcessed($subscriber_id) {
21
+ $subscriber = $this->getSubscribers()
22
+ ->where('subscriber_id', $subscriber_id)
23
+ ->findOne();
24
+ return !empty($subscriber);
25
+ }
26
+
27
+ function removeSubscribers($subscribers_to_remove) {
28
+ $this->getSubscribers()
29
+ ->whereIn('subscriber_id', $subscribers_to_remove)
30
+ ->deleteMany();
31
+ $this->checkCompleted();
32
+ }
33
+
34
+ function updateProcessedSubscribers(array $processed_subscribers) {
35
+ $this->getSubscribers()
36
+ ->whereIn('subscriber_id', $processed_subscribers)
37
+ ->findResultSet()
38
+ ->set('processed', ScheduledTaskSubscriber::STATUS_PROCESSED)
39
+ ->save();
40
+ $this->checkCompleted();
41
+ }
42
+
43
+ private function checkCompleted() {
44
+ if(!ScheduledTaskSubscriber::getUnprocessedCount($this->task->id)) {
45
+ $this->task->complete();
46
+ }
47
+ }
48
+ }
lib/Tasks/Subscribers/BatchIterator.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace MailPoet\Tasks\Subscribers;
3
+
4
+ use MailPoet\Models\ScheduledTaskSubscriber;
5
+ use MailPoet\Util\Helpers;
6
+
7
+ if(!defined('ABSPATH')) exit;
8
+
9
+ class BatchIterator implements \Iterator, \Countable {
10
+ private $task_id;
11
+ private $batch_size;
12
+ private $last_processed_id = 0;
13
+ private $batch_last_id;
14
+
15
+ function __construct($task_id, $batch_size) {
16
+ if($task_id <= 0) {
17
+ throw new \Exception('Task ID must be greater than zero');
18
+ } elseif($batch_size <= 0) {
19
+ throw new \Exception('Batch size must be greater than zero');
20
+ }
21
+ $this->task_id = (int)$task_id;
22
+ $this->batch_size = (int)$batch_size;
23
+ }
24
+
25
+ function rewind() {
26
+ $this->last_processed_id = 0;
27
+ }
28
+
29
+ function current() {
30
+ $subscribers = $this->getSubscribers()
31
+ ->orderByAsc('subscriber_id')
32
+ ->limit($this->batch_size)
33
+ ->findArray();
34
+ $subscribers = Helpers::arrayColumn($subscribers, 'subscriber_id');
35
+ $this->batch_last_id = end($subscribers);
36
+ return $subscribers;
37
+ }
38
+
39
+ function key() {
40
+ return null;
41
+ }
42
+
43
+ function next() {
44
+ $this->last_processed_id = $this->batch_last_id;
45
+ }
46
+
47
+ function valid() {
48
+ return $this->count() > 0;
49
+ }
50
+
51
+ function count() {
52
+ return $this->getSubscribers()->count();
53
+ }
54
+
55
+ private function getSubscribers() {
56
+ return ScheduledTaskSubscriber::select('subscriber_id')
57
+ ->where('task_id', $this->task_id)
58
+ ->whereGt('subscriber_id', $this->last_processed_id)
59
+ ->where('processed', ScheduledTaskSubscriber::STATUS_UNPROCESSED);
60
+ }
61
+ }
lib/Tasks/Subscribers/index.php ADDED
File without changes
lib/Tasks/index.php ADDED
File without changes
lib/Twig/Functions.php CHANGED
@@ -61,6 +61,11 @@ class Functions extends \Twig_Extension {
61
  array($this, 'getMailPoetVersion'),
62
  array('is_safe' => array('all'))
63
  ),
 
 
 
 
 
64
  new \Twig_SimpleFunction(
65
  'wp_time_format',
66
  array($this, 'getWPTimeFormat'),
@@ -125,6 +130,10 @@ class Functions extends \Twig_Extension {
125
  return MAILPOET_VERSION;
126
  }
127
 
 
 
 
 
128
  function getWPTimeFormat() {
129
  return (get_option('time_format')) ?
130
  get_option('time_format') :
61
  array($this, 'getMailPoetVersion'),
62
  array('is_safe' => array('all'))
63
  ),
64
+ new \Twig_SimpleFunction(
65
+ 'mailpoet_premium_version',
66
+ array($this, 'getMailPoetPremiumVersion'),
67
+ array('is_safe' => array('all'))
68
+ ),
69
  new \Twig_SimpleFunction(
70
  'wp_time_format',
71
  array($this, 'getWPTimeFormat'),
130
  return MAILPOET_VERSION;
131
  }
132
 
133
+ function getMailPoetPremiumVersion() {
134
+ return (defined('MAILPOET_PREMIUM_VERSION')) ? MAILPOET_PREMIUM_VERSION : false;
135
+ }
136
+
137
  function getWPTimeFormat() {
138
  return (get_option('time_format')) ?
139
  get_option('time_format') :
mailpoet.php CHANGED
@@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
4
 
5
  /*
6
  * Plugin Name: MailPoet
7
- * Version: 3.0.0-beta.36.3.1
8
  * Plugin URI: http://www.mailpoet.com
9
  * Description: Create and send beautiful email newsletters, autoresponders, and post notifications without leaving WordPress. This is a beta version of our brand new plugin!
10
  * Author: MailPoet
@@ -21,7 +21,7 @@ if(!defined('ABSPATH')) exit;
21
  */
22
 
23
  $mailpoet_plugin = array(
24
- 'version' => '3.0.0-beta.36.3.1',
25
  'filename' => __FILE__,
26
  'path' => dirname(__FILE__),
27
  'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
4
 
5
  /*
6
  * Plugin Name: MailPoet
7
+ * Version: 3.0.0-beta.37.0.0
8
  * Plugin URI: http://www.mailpoet.com
9
  * Description: Create and send beautiful email newsletters, autoresponders, and post notifications without leaving WordPress. This is a beta version of our brand new plugin!
10
  * Author: MailPoet
21
  */
22
 
23
  $mailpoet_plugin = array(
24
+ 'version' => '3.0.0-beta.37.0.0',
25
  'filename' => __FILE__,
26
  'path' => dirname(__FILE__),
27
  'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: mailpoet, wysija
3
  Tags: newsletter, email, welcome email, post notification, autoresponder, signup, subscription, SMTP
4
  Requires at least: 4.6
5
  Tested up to: 4.8
6
- Stable tag: 3.0.0-beta.36.3.1
7
  Create and send beautiful emails and newsletters from WordPress.
8
 
9
  == Description ==
@@ -22,7 +22,7 @@ Try the new MailPoet! This is a beta version of our completely new email newslet
22
 
23
  = See it in action. =
24
  [Test the demo](http://demo3.mailpoet.com/launch/) or [see the 2 min. video](https://vimeo.com/223581490)
25
- [vimeo https://vimeo.com/223581490]
26
 
27
  = What is a beta? =
28
 
@@ -93,6 +93,13 @@ Our [support site](https://beta.docs.mailpoet.com) has plenty of articles. You c
93
 
94
  == Changelog ==
95
 
 
 
 
 
 
 
 
96
  = 3.0.0-beta.36.3.1 - 2017-07-18 =
97
  * Added: you can now duplicate any item in the email designer;
98
  * Improved: added filter to specify custom SMTP connection timeout value. Thanks, Rik;
3
  Tags: newsletter, email, welcome email, post notification, autoresponder, signup, subscription, SMTP
4
  Requires at least: 4.6
5
  Tested up to: 4.8
6
+ Stable tag: 3.0.0-beta.37.0.0
7
  Create and send beautiful emails and newsletters from WordPress.
8
 
9
  == Description ==
22
 
23
  = See it in action. =
24
  [Test the demo](http://demo3.mailpoet.com/launch/) or [see the 2 min. video](https://vimeo.com/223581490)
25
+ [vimeo https://vimeo.com/223581490]
26
 
27
  = What is a beta? =
28
 
93
 
94
  == Changelog ==
95
 
96
+ = 3.0.0-beta.37.0.0 - 2017-07-25 =
97
+ * Improved: we collect more informative data from those who share it with us in order to improve the plugin. You should share too!
98
+ * Fixed: deleted WordPress users are removed from the WordPress Users list as well;
99
+ * Fixed: shortcodes for custom fields are now inserted correctly in the email designer;
100
+ * Fixed: MailPoet Sending Service stays activated after saving Settings;
101
+ * Fixed: improperly rendered newsletters will not be sent. Thanks Scott and Alison!
102
+
103
  = 3.0.0-beta.36.3.1 - 2017-07-18 =
104
  * Added: you can now duplicate any item in the email designer;
105
  * Improved: added filter to specify custom SMTP connection timeout value. Thanks, Rik;
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit0cb1ee30fabb15d2899414384ee4767a::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitc1e89694b49645f6e943193c78aeabbb::getLoader();
vendor/composer/ClassLoader.php CHANGED
@@ -55,7 +55,6 @@ class ClassLoader
55
  private $classMap = array();
56
  private $classMapAuthoritative = false;
57
  private $missingClasses = array();
58
- private $apcuPrefix;
59
 
60
  public function getPrefixes()
61
  {
@@ -272,26 +271,6 @@ class ClassLoader
272
  return $this->classMapAuthoritative;
273
  }
274
 
275
- /**
276
- * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277
- *
278
- * @param string|null $apcuPrefix
279
- */
280
- public function setApcuPrefix($apcuPrefix)
281
- {
282
- $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
283
- }
284
-
285
- /**
286
- * The APCu prefix in use, or null if APCu caching is not enabled.
287
- *
288
- * @return string|null
289
- */
290
- public function getApcuPrefix()
291
- {
292
- return $this->apcuPrefix;
293
- }
294
-
295
  /**
296
  * Registers this instance as an autoloader.
297
  *
@@ -334,6 +313,11 @@ class ClassLoader
334
  */
335
  public function findFile($class)
336
  {
 
 
 
 
 
337
  // class map lookup
338
  if (isset($this->classMap[$class])) {
339
  return $this->classMap[$class];
@@ -341,12 +325,6 @@ class ClassLoader
341
  if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
342
  return false;
343
  }
344
- if (null !== $this->apcuPrefix) {
345
- $file = apcu_fetch($this->apcuPrefix.$class, $hit);
346
- if ($hit) {
347
- return $file;
348
- }
349
- }
350
 
351
  $file = $this->findFileWithExtension($class, '.php');
352
 
@@ -355,10 +333,6 @@ class ClassLoader
355
  $file = $this->findFileWithExtension($class, '.hh');
356
  }
357
 
358
- if (null !== $this->apcuPrefix) {
359
- apcu_add($this->apcuPrefix.$class, $file);
360
- }
361
-
362
  if (false === $file) {
363
  // Remember that this class does not exist.
364
  $this->missingClasses[$class] = true;
55
  private $classMap = array();
56
  private $classMapAuthoritative = false;
57
  private $missingClasses = array();
 
58
 
59
  public function getPrefixes()
60
  {
271
  return $this->classMapAuthoritative;
272
  }
273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  /**
275
  * Registers this instance as an autoloader.
276
  *
313
  */
314
  public function findFile($class)
315
  {
316
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317
+ if ('\\' == $class[0]) {
318
+ $class = substr($class, 1);
319
+ }
320
+
321
  // class map lookup
322
  if (isset($this->classMap[$class])) {
323
  return $this->classMap[$class];
325
  if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
326
  return false;
327
  }
 
 
 
 
 
 
328
 
329
  $file = $this->findFileWithExtension($class, '.php');
330
 
333
  $file = $this->findFileWithExtension($class, '.hh');
334
  }
335
 
 
 
 
 
336
  if (false === $file) {
337
  // Remember that this class does not exist.
338
  $this->missingClasses[$class] = true;
vendor/composer/autoload_classmap.php CHANGED
@@ -151,6 +151,7 @@ return array(
151
  'MailPoet\\Models\\NewsletterSegment' => $baseDir . '/lib/Models/NewsletterSegment.php',
152
  'MailPoet\\Models\\NewsletterTemplate' => $baseDir . '/lib/Models/NewsletterTemplate.php',
153
  'MailPoet\\Models\\ScheduledTask' => $baseDir . '/lib/Models/ScheduledTask.php',
 
154
  'MailPoet\\Models\\Segment' => $baseDir . '/lib/Models/Segment.php',
155
  'MailPoet\\Models\\SendingQueue' => $baseDir . '/lib/Models/SendingQueue.php',
156
  'MailPoet\\Models\\Setting' => $baseDir . '/lib/Models/Setting.php',
@@ -219,6 +220,9 @@ return array(
219
  'MailPoet\\Subscription\\Pages' => $baseDir . '/lib/Subscription/Pages.php',
220
  'MailPoet\\Subscription\\Registration' => $baseDir . '/lib/Subscription/Registration.php',
221
  'MailPoet\\Subscription\\Url' => $baseDir . '/lib/Subscription/Url.php',
 
 
 
222
  'MailPoet\\Twig\\Analytics' => $baseDir . '/lib/Twig/Analytics.php',
223
  'MailPoet\\Twig\\Assets' => $baseDir . '/lib/Twig/Assets.php',
224
  'MailPoet\\Twig\\Filters' => $baseDir . '/lib/Twig/Filters.php',
151
  'MailPoet\\Models\\NewsletterSegment' => $baseDir . '/lib/Models/NewsletterSegment.php',
152
  'MailPoet\\Models\\NewsletterTemplate' => $baseDir . '/lib/Models/NewsletterTemplate.php',
153
  'MailPoet\\Models\\ScheduledTask' => $baseDir . '/lib/Models/ScheduledTask.php',
154
+ 'MailPoet\\Models\\ScheduledTaskSubscriber' => $baseDir . '/lib/Models/ScheduledTaskSubscriber.php',
155
  'MailPoet\\Models\\Segment' => $baseDir . '/lib/Models/Segment.php',
156
  'MailPoet\\Models\\SendingQueue' => $baseDir . '/lib/Models/SendingQueue.php',
157
  'MailPoet\\Models\\Setting' => $baseDir . '/lib/Models/Setting.php',
220
  'MailPoet\\Subscription\\Pages' => $baseDir . '/lib/Subscription/Pages.php',
221
  'MailPoet\\Subscription\\Registration' => $baseDir . '/lib/Subscription/Registration.php',
222
  'MailPoet\\Subscription\\Url' => $baseDir . '/lib/Subscription/Url.php',
223
+ 'MailPoet\\Tasks\\Bounce' => $baseDir . '/lib/Tasks/Bounce.php',
224
+ 'MailPoet\\Tasks\\Subscribers' => $baseDir . '/lib/Tasks/Subscribers.php',
225
+ 'MailPoet\\Tasks\\Subscribers\\BatchIterator' => $baseDir . '/lib/Tasks/Subscribers/BatchIterator.php',
226
  'MailPoet\\Twig\\Analytics' => $baseDir . '/lib/Twig/Analytics.php',
227
  'MailPoet\\Twig\\Assets' => $baseDir . '/lib/Twig/Assets.php',
228
  'MailPoet\\Twig\\Filters' => $baseDir . '/lib/Twig/Filters.php',
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit0cb1ee30fabb15d2899414384ee4767a
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit0cb1ee30fabb15d2899414384ee4767a
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit0cb1ee30fabb15d2899414384ee4767a', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit0cb1ee30fabb15d2899414384ee4767a', '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\ComposerStaticInit0cb1ee30fabb15d2899414384ee4767a::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit0cb1ee30fabb15d2899414384ee4767a
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
- $includeFiles = Composer\Autoload\ComposerStaticInit0cb1ee30fabb15d2899414384ee4767a::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
- composerRequire0cb1ee30fabb15d2899414384ee4767a($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
- function composerRequire0cb1ee30fabb15d2899414384ee4767a($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 ComposerAutoloaderInitc1e89694b49645f6e943193c78aeabbb
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitc1e89694b49645f6e943193c78aeabbb', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitc1e89694b49645f6e943193c78aeabbb', 'loadClassLoader'));
25
 
26
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInitc1e89694b49645f6e943193c78aeabbb::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\ComposerStaticInitc1e89694b49645f6e943193c78aeabbb::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequirec1e89694b49645f6e943193c78aeabbb($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
+ function composerRequirec1e89694b49645f6e943193c78aeabbb($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 ComposerStaticInit0cb1ee30fabb15d2899414384ee4767a
8
  {
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@@ -233,6 +233,7 @@ class ComposerStaticInit0cb1ee30fabb15d2899414384ee4767a
233
  'MailPoet\\Models\\NewsletterSegment' => __DIR__ . '/../..' . '/lib/Models/NewsletterSegment.php',
234
  'MailPoet\\Models\\NewsletterTemplate' => __DIR__ . '/../..' . '/lib/Models/NewsletterTemplate.php',
235
  'MailPoet\\Models\\ScheduledTask' => __DIR__ . '/../..' . '/lib/Models/ScheduledTask.php',
 
236
  'MailPoet\\Models\\Segment' => __DIR__ . '/../..' . '/lib/Models/Segment.php',
237
  'MailPoet\\Models\\SendingQueue' => __DIR__ . '/../..' . '/lib/Models/SendingQueue.php',
238
  'MailPoet\\Models\\Setting' => __DIR__ . '/../..' . '/lib/Models/Setting.php',
@@ -301,6 +302,9 @@ class ComposerStaticInit0cb1ee30fabb15d2899414384ee4767a
301
  'MailPoet\\Subscription\\Pages' => __DIR__ . '/../..' . '/lib/Subscription/Pages.php',
302
  'MailPoet\\Subscription\\Registration' => __DIR__ . '/../..' . '/lib/Subscription/Registration.php',
303
  'MailPoet\\Subscription\\Url' => __DIR__ . '/../..' . '/lib/Subscription/Url.php',
 
 
 
304
  'MailPoet\\Twig\\Analytics' => __DIR__ . '/../..' . '/lib/Twig/Analytics.php',
305
  'MailPoet\\Twig\\Assets' => __DIR__ . '/../..' . '/lib/Twig/Assets.php',
306
  'MailPoet\\Twig\\Filters' => __DIR__ . '/../..' . '/lib/Twig/Filters.php',
@@ -649,10 +653,10 @@ class ComposerStaticInit0cb1ee30fabb15d2899414384ee4767a
649
  public static function getInitializer(ClassLoader $loader)
650
  {
651
  return \Closure::bind(function () use ($loader) {
652
- $loader->prefixLengthsPsr4 = ComposerStaticInit0cb1ee30fabb15d2899414384ee4767a::$prefixLengthsPsr4;
653
- $loader->prefixDirsPsr4 = ComposerStaticInit0cb1ee30fabb15d2899414384ee4767a::$prefixDirsPsr4;
654
- $loader->prefixesPsr0 = ComposerStaticInit0cb1ee30fabb15d2899414384ee4767a::$prefixesPsr0;
655
- $loader->classMap = ComposerStaticInit0cb1ee30fabb15d2899414384ee4767a::$classMap;
656
 
657
  }, null, ClassLoader::class);
658
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInitc1e89694b49645f6e943193c78aeabbb
8
  {
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
233
  'MailPoet\\Models\\NewsletterSegment' => __DIR__ . '/../..' . '/lib/Models/NewsletterSegment.php',
234
  'MailPoet\\Models\\NewsletterTemplate' => __DIR__ . '/../..' . '/lib/Models/NewsletterTemplate.php',
235
  'MailPoet\\Models\\ScheduledTask' => __DIR__ . '/../..' . '/lib/Models/ScheduledTask.php',
236
+ 'MailPoet\\Models\\ScheduledTaskSubscriber' => __DIR__ . '/../..' . '/lib/Models/ScheduledTaskSubscriber.php',
237
  'MailPoet\\Models\\Segment' => __DIR__ . '/../..' . '/lib/Models/Segment.php',
238
  'MailPoet\\Models\\SendingQueue' => __DIR__ . '/../..' . '/lib/Models/SendingQueue.php',
239
  'MailPoet\\Models\\Setting' => __DIR__ . '/../..' . '/lib/Models/Setting.php',
302
  'MailPoet\\Subscription\\Pages' => __DIR__ . '/../..' . '/lib/Subscription/Pages.php',
303
  'MailPoet\\Subscription\\Registration' => __DIR__ . '/../..' . '/lib/Subscription/Registration.php',
304
  'MailPoet\\Subscription\\Url' => __DIR__ . '/../..' . '/lib/Subscription/Url.php',
305
+ 'MailPoet\\Tasks\\Bounce' => __DIR__ . '/../..' . '/lib/Tasks/Bounce.php',
306
+ 'MailPoet\\Tasks\\Subscribers' => __DIR__ . '/../..' . '/lib/Tasks/Subscribers.php',
307
+ 'MailPoet\\Tasks\\Subscribers\\BatchIterator' => __DIR__ . '/../..' . '/lib/Tasks/Subscribers/BatchIterator.php',
308
  'MailPoet\\Twig\\Analytics' => __DIR__ . '/../..' . '/lib/Twig/Analytics.php',
309
  'MailPoet\\Twig\\Assets' => __DIR__ . '/../..' . '/lib/Twig/Assets.php',
310
  'MailPoet\\Twig\\Filters' => __DIR__ . '/../..' . '/lib/Twig/Filters.php',
653
  public static function getInitializer(ClassLoader $loader)
654
  {
655
  return \Closure::bind(function () use ($loader) {
656
+ $loader->prefixLengthsPsr4 = ComposerStaticInitc1e89694b49645f6e943193c78aeabbb::$prefixLengthsPsr4;
657
+ $loader->prefixDirsPsr4 = ComposerStaticInitc1e89694b49645f6e943193c78aeabbb::$prefixDirsPsr4;
658
+ $loader->prefixesPsr0 = ComposerStaticInitc1e89694b49645f6e943193c78aeabbb::$prefixesPsr0;
659
+ $loader->classMap = ComposerStaticInitc1e89694b49645f6e943193c78aeabbb::$classMap;
660
 
661
  }, null, ClassLoader::class);
662
  }
vendor/composer/installed.json CHANGED
@@ -14,7 +14,7 @@
14
  "reference": "b0c1bda3be5a35da44ba1ac28cc61c67d2ada465",
15
  "shasum": ""
16
  },
17
- "time": "2015-11-28T21:47:43+00:00",
18
  "type": "library",
19
  "installation-source": "dist",
20
  "autoload": {
@@ -55,7 +55,7 @@
55
  "require-dev": {
56
  "phpunit/phpunit": "^5.6"
57
  },
58
- "time": "2016-12-14T06:28:26+00:00",
59
  "type": "library",
60
  "installation-source": "dist",
61
  "autoload": {
@@ -116,7 +116,7 @@
116
  "j4mie/idiorm": "1.5.*",
117
  "php": ">=5.2.0"
118
  },
119
- "time": "2014-09-23T10:49:36+00:00",
120
  "type": "library",
121
  "installation-source": "dist",
122
  "autoload": {
@@ -180,7 +180,7 @@
180
  "require-dev": {
181
  "phpunit/phpunit": "~4.0|~5.0"
182
  },
183
- "time": "2017-01-23T04:29:33+00:00",
184
  "type": "library",
185
  "installation-source": "dist",
186
  "autoload": {
@@ -226,7 +226,7 @@
226
  "suggest": {
227
  "ext-mbstring": "For best performance"
228
  },
229
- "time": "2016-11-14T01:06:16+00:00",
230
  "type": "library",
231
  "extra": {
232
  "branch-alias": {
@@ -299,7 +299,7 @@
299
  "symfony/config": "",
300
  "symfony/yaml": ""
301
  },
302
- "time": "2017-03-04T12:20:59+00:00",
303
  "type": "library",
304
  "extra": {
305
  "branch-alias": {
@@ -355,7 +355,7 @@
355
  "friendsofphp/php-cs-fixer": "~2",
356
  "phpunit/phpunit": "~4.0 || ~5.0"
357
  },
358
- "time": "2017-01-16T07:55:07+00:00",
359
  "type": "library",
360
  "extra": {
361
  "branch-alias": {
@@ -408,7 +408,7 @@
408
  "require-dev": {
409
  "phpunit/phpunit": "*"
410
  },
411
- "time": "2016-07-19T19:14:21+00:00",
412
  "type": "library",
413
  "installation-source": "dist",
414
  "autoload": {
@@ -457,7 +457,7 @@
457
  "phpunit/phpunit": ">=4.0",
458
  "soundasleep/component-tests": "dev-master"
459
  },
460
- "time": "2016-06-09T04:56:16+00:00",
461
  "type": "library",
462
  "installation-source": "dist",
463
  "autoload": {
@@ -510,7 +510,7 @@
510
  "mockery/mockery": "~0.9.1",
511
  "symfony/phpunit-bridge": "~3.2"
512
  },
513
- "time": "2017-02-13T07:52:53+00:00",
514
  "type": "library",
515
  "extra": {
516
  "branch-alias": {
@@ -565,7 +565,7 @@
565
  "suggest": {
566
  "ext-xml": "For best performance"
567
  },
568
- "time": "2016-11-14T01:06:16+00:00",
569
  "type": "library",
570
  "extra": {
571
  "branch-alias": {
@@ -625,7 +625,7 @@
625
  "require-dev": {
626
  "htmlawed/htmlawed": "dev-master"
627
  },
628
- "time": "2016-01-14T20:55:00+00:00",
629
  "type": "library",
630
  "installation-source": "dist",
631
  "autoload": {
@@ -681,7 +681,7 @@
681
  "symfony/debug": "~2.7",
682
  "symfony/phpunit-bridge": "~3.2"
683
  },
684
- "time": "2017-02-27T00:07:03+00:00",
685
  "type": "library",
686
  "extra": {
687
  "branch-alias": {
14
  "reference": "b0c1bda3be5a35da44ba1ac28cc61c67d2ada465",
15
  "shasum": ""
16
  },
17
+ "time": "2015-11-28 21:47:43",
18
  "type": "library",
19
  "installation-source": "dist",
20
  "autoload": {
55
  "require-dev": {
56
  "phpunit/phpunit": "^5.6"
57
  },
58
+ "time": "2016-12-14 06:28:26",
59
  "type": "library",
60
  "installation-source": "dist",
61
  "autoload": {
116
  "j4mie/idiorm": "1.5.*",
117
  "php": ">=5.2.0"
118
  },
119
+ "time": "2014-09-23 10:49:36",
120
  "type": "library",
121
  "installation-source": "dist",
122
  "autoload": {
180
  "require-dev": {
181
  "phpunit/phpunit": "~4.0|~5.0"
182
  },
183
+ "time": "2017-01-23 04:29:33",
184
  "type": "library",
185
  "installation-source": "dist",
186
  "autoload": {
226
  "suggest": {
227
  "ext-mbstring": "For best performance"
228
  },
229
+ "time": "2016-11-14 01:06:16",
230
  "type": "library",
231
  "extra": {
232
  "branch-alias": {
299
  "symfony/config": "",
300
  "symfony/yaml": ""
301
  },
302
+ "time": "2017-03-04 12:20:59",
303
  "type": "library",
304
  "extra": {
305
  "branch-alias": {
355
  "friendsofphp/php-cs-fixer": "~2",
356
  "phpunit/phpunit": "~4.0 || ~5.0"
357
  },
358
+ "time": "2017-01-16 07:55:07",
359
  "type": "library",
360
  "extra": {
361
  "branch-alias": {
408
  "require-dev": {
409
  "phpunit/phpunit": "*"
410
  },
411
+ "time": "2016-07-19 19:14:21",
412
  "type": "library",
413
  "installation-source": "dist",
414
  "autoload": {
457
  "phpunit/phpunit": ">=4.0",
458
  "soundasleep/component-tests": "dev-master"
459
  },
460
+ "time": "2016-06-09 04:56:16",
461
  "type": "library",
462
  "installation-source": "dist",
463
  "autoload": {
510
  "mockery/mockery": "~0.9.1",
511
  "symfony/phpunit-bridge": "~3.2"
512
  },
513
+ "time": "2017-02-13 07:52:53",
514
  "type": "library",
515
  "extra": {
516
  "branch-alias": {
565
  "suggest": {
566
  "ext-xml": "For best performance"
567
  },
568
+ "time": "2016-11-14 01:06:16",
569
  "type": "library",
570
  "extra": {
571
  "branch-alias": {
625
  "require-dev": {
626
  "htmlawed/htmlawed": "dev-master"
627
  },
628
+ "time": "2016-01-14 20:55:00",
629
  "type": "library",
630
  "installation-source": "dist",
631
  "autoload": {
681
  "symfony/debug": "~2.7",
682
  "symfony/phpunit-bridge": "~3.2"
683
  },
684
+ "time": "2017-02-27 00:07:03",
685
  "type": "library",
686
  "extra": {
687
  "branch-alias": {
views/layout.html CHANGED
@@ -45,6 +45,7 @@ jQuery('.toplevel_page_mailpoet-newsletters.menu-top-last')
45
  var mailpoet_date_format = "<%= wp_datetime_format()|escape('js') %>";
46
  var mailpoet_time_format = "<%= wp_time_format()|escape('js') %>";
47
  var mailpoet_version = "<%= mailpoet_version() %>";
 
48
  var mailpoet_analytics_enabled = <%= is_analytics_enabled() | json_encode %>;
49
  var mailpoet_analytics_data = <%= json_encode(get_analytics_data()) %>;
50
  </script>
45
  var mailpoet_date_format = "<%= wp_datetime_format()|escape('js') %>";
46
  var mailpoet_time_format = "<%= wp_time_format()|escape('js') %>";
47
  var mailpoet_version = "<%= mailpoet_version() %>";
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>
views/premium.html CHANGED
@@ -2,16 +2,18 @@
2
 
3
  <% block content %>
4
 
5
- <style type="text/css">
6
- .mailpoet_video {
7
- border: 1px solid rgba(0, 0, 0, 0.1);
8
- }
9
- </style>
10
-
11
  <div class="wrap mailpoet-about-wrap">
12
  <h1 style="text-align: center; margin-right: 0;"><%= __('What is MailPoet Premium?') %></h1>
13
 
14
- <p class="about-text" style="text-align: center; margin-right: 0;"><%= __("Detailed statistics, actionable insights, awesome deliverability, plus great support!") %></p>
 
 
 
 
 
 
 
 
15
 
16
  <hr>
17
 
@@ -31,7 +33,7 @@
31
  <h2><%= __("Hello Inbox, Goodbye Spambox!") %></h2>
32
 
33
  <div class="feature-section one-col">
34
- <p class="lead-description"><%= __("The MailPoet Sending Service's delivery rate is over 98%: one of the best in the industry! Our in-house sending service is constantly monitored, tweaked, and improved to make sure that your emails arrive successfully.") %></p>
35
  <table class="widefat">
36
  <thead>
37
  <tr>
@@ -73,17 +75,16 @@
73
  <td><%= __("Depends") %></td>
74
  </tr>
75
  <tr>
76
- <td>
77
- <a
78
- href="http://beta.docs.mailpoet.com/article/181-comparison-table-of-sending-methods?utm_source=plugin&utm_medium=premium&utm_campaign=compare"
79
- target="_blank"
80
- >
81
- <%= __("View full comparison table") %>
82
- </a>
 
 
83
  </td>
84
- <td></td>
85
- <td></td>
86
- <td></td>
87
  </tr>
88
  </tbody>
89
  </table>
@@ -120,8 +121,8 @@
120
 
121
  <h2><%= __("Get Started for Just $10") %></h2>
122
 
123
- <div clas="feature-section one-col">
124
- <p class="lead-description"><%= __("Our plans start at just $10 per month. Each plan offers unlimited emails. Pricing scales up with the size of your list.") %></p>
125
  <br>
126
  <p style="text-align: center">
127
  <a
2
 
3
  <% block content %>
4
 
 
 
 
 
 
 
5
  <div class="wrap mailpoet-about-wrap">
6
  <h1 style="text-align: center; margin-right: 0;"><%= __('What is MailPoet Premium?') %></h1>
7
 
8
+ <p class="about-text" style="text-align: center; margin-right: 0;"><%= __("Check out the brief video below. Or, keep reading!") %></p>
9
+
10
+ <hr>
11
+
12
+ <div class="headline-feature feature-video">
13
+ <div class="videoWrapper">
14
+ <iframe src="https://player.vimeo.com/video/225337083" width="1050" height="591" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
15
+ </div>
16
+ </div>
17
 
18
  <hr>
19
 
33
  <h2><%= __("Hello Inbox, Goodbye Spambox!") %></h2>
34
 
35
  <div class="feature-section one-col">
36
+ <p class="lead-description"><%= __("Having issues with reaching your subscribers? Always ending up in the spam box? Don't panic! You're not alone - over a quarter of our plugin users have sending issues, usually because they are sending emails via their web host. Instead, try using the new MailPoet Sending Service.") %></p>
37
  <table class="widefat">
38
  <thead>
39
  <tr>
75
  <td><%= __("Depends") %></td>
76
  </tr>
77
  <tr>
78
+ <td colspan="4">
79
+ <div style="text-align: center">
80
+ <a
81
+ href="http://beta.docs.mailpoet.com/article/181-comparison-table-of-sending-methods?utm_source=plugin&utm_medium=premium&utm_campaign=compare"
82
+ target="_blank"
83
+ >
84
+ <%= __("View full comparison table") %>
85
+ </a>
86
+ </div>
87
  </td>
 
 
 
88
  </tr>
89
  </tbody>
90
  </table>
121
 
122
  <h2><%= __("Get Started for Just $10") %></h2>
123
 
124
+ <div class="feature-section one-col">
125
+ <p class="lead-description"><%= __("Our plans start at just $10 per month. Plus, if you pay annually, you’ll get two months for free!") %></p>
126
  <br>
127
  <p style="text-align: center">
128
  <a
views/settings.html CHANGED
@@ -97,6 +97,19 @@
97
  "<%= __('Settings saved') | escape('js') %>",
98
  { scroll: true }
99
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  }).fail(function(response) {
101
  if (response.errors.length > 0) {
102
  MailPoet.Notice.error(
97
  "<%= __('Settings saved') | escape('js') %>",
98
  { scroll: true }
99
  );
100
+ MailPoet.trackEvent(
101
+ 'User has saved Settings',
102
+ {
103
+ 'MailPoet Free version': window.mailpoet_version,
104
+ 'Sending method type': settings_data.mta_group || null,
105
+ 'Sending frequency (emails)': settings_data.mta_group != 'mailpoet' && settings_data.mta && settings_data.mta.frequency && settings_data.mta.frequency.emails,
106
+ 'Sending frequency (interval)': settings_data.mta_group != 'mailpoet' && settings_data.mta && settings_data.mta.frequency && settings_data.mta.frequency.interval,
107
+ 'Sending provider': settings_data.mta_group == 'smtp' && settings_data.smtp_provider,
108
+ 'Sign-up confirmation enabled': (settings_data.signup_confirmation && settings_data.signup_confirmation.enabled == true),
109
+ 'Bounce email is present': (settings_data.bounce && settings_data.bounce.address != ""),
110
+ 'Newsletter task scheduler method': (settings_data.cron_trigger && settings_data.cron_trigger.method)
111
+ }
112
+ );
113
  }).fail(function(response) {
114
  if (response.errors.length > 0) {
115
  MailPoet.Notice.error(
views/settings/mta.html CHANGED
@@ -724,6 +724,7 @@
724
  "<%= __('The email has been sent! Check your inbox.') | escape('js') %>",
725
  { scroll: true }
726
  );
 
727
  }).fail(function(response) {
728
  if (response.errors.length > 0) {
729
  MailPoet.Notice.error(
@@ -731,6 +732,7 @@
731
  { scroll: true }
732
  );
733
  }
 
734
  });
735
  });
736
 
@@ -757,8 +759,11 @@
757
  });
758
  $('#mailpoet_smtp_method').on('change keyup', renderHostsSelect);
759
  $('#mailpoet_sending_frequency').on('change keyup', sendingFrequencyMethodUpdated);
760
- $('#mailpoet_smtp_method').trigger("change");
761
- $('#other_frequency_emails').trigger("change");
 
 
 
762
 
763
  function saveSendingMethodConfiguration(group) {
764
 
@@ -858,6 +863,24 @@
858
  // render sending frequency form
859
  $('#mailpoet_smtp_provider').trigger('change');
860
  $('#mailpoet_web_host').trigger('change');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
861
  });
862
 
863
  function setProviderForm() {
724
  "<%= __('The email has been sent! Check your inbox.') | escape('js') %>",
725
  { scroll: true }
726
  );
727
+ trackTestEmailSent(true);
728
  }).fail(function(response) {
729
  if (response.errors.length > 0) {
730
  MailPoet.Notice.error(
732
  { scroll: true }
733
  );
734
  }
735
+ trackTestEmailSent(false);
736
  });
737
  });
738
 
759
  });
760
  $('#mailpoet_smtp_method').on('change keyup', renderHostsSelect);
761
  $('#mailpoet_sending_frequency').on('change keyup', sendingFrequencyMethodUpdated);
762
+
763
+ <% if(settings.mta_group != 'mailpoet') %>
764
+ $('#mailpoet_smtp_method').trigger("change");
765
+ $('#other_frequency_emails').trigger("change");
766
+ <% endif %>
767
 
768
  function saveSendingMethodConfiguration(group) {
769
 
863
  // render sending frequency form
864
  $('#mailpoet_smtp_provider').trigger('change');
865
  $('#mailpoet_web_host').trigger('change');
866
+
867
+ function trackTestEmailSent(success) {
868
+ MailPoet.trackEvent(
869
+ 'User has sent a test email from Settings',
870
+ {
871
+ 'Sending was successful': !!success,
872
+ 'Sending method type': mailer.method,
873
+ 'MailPoet Free version': window.mailpoet_version
874
+ }
875
+ );
876
+ }
877
+
878
+ $('.mailpoet_sending_methods_help a').on('click', function() {
879
+ MailPoet.trackEvent(
880
+ 'User has clicked to view the sending comparison table',
881
+ {'MailPoet Free version': window.mailpoet_version}
882
+ );
883
+ });
884
  });
885
 
886
  function setProviderForm() {
views/settings/premium.html CHANGED
@@ -146,6 +146,13 @@
146
  .attr('href', response.meta.premium_activate_url || '#');
147
  $('.mailpoet_premium_activate').show();
148
  }
 
 
 
 
 
 
 
149
  }).fail(function(response) {
150
  if (response.errors.length > 0) {
151
  $('.mailpoet_premium_key_invalid').text(
@@ -153,6 +160,13 @@
153
  );
154
  $('.mailpoet_premium_key_invalid').removeClass('mailpoet_hidden');
155
  }
 
 
 
 
 
 
 
156
  });
157
  }
158
 
@@ -184,6 +198,20 @@
184
  });
185
  }
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  });
188
  });
189
  </script>
146
  .attr('href', response.meta.premium_activate_url || '#');
147
  $('.mailpoet_premium_activate').show();
148
  }
149
+ MailPoet.trackEvent(
150
+ 'User has validated a Premium key',
151
+ {
152
+ 'MailPoet Free version': window.mailpoet_version,
153
+ 'Premium plugin is active': response.meta.premium_plugin_active
154
+ }
155
+ );
156
  }).fail(function(response) {
157
  if (response.errors.length > 0) {
158
  $('.mailpoet_premium_key_invalid').text(
160
  );
161
  $('.mailpoet_premium_key_invalid').removeClass('mailpoet_hidden');
162
  }
163
+ MailPoet.trackEvent(
164
+ 'User has failed to validate a Premium key',
165
+ {
166
+ 'MailPoet Free version': window.mailpoet_version,
167
+ 'Premium plugin is active': !!window.mailpoet_premium_version
168
+ }
169
+ );
170
  });
171
  }
172
 
198
  });
199
  }
200
 
201
+ $('.mailpoet_premium_install_link').on('click', function() {
202
+ MailPoet.trackEvent(
203
+ 'User has installed the Premium plugin from Settings',
204
+ {'MailPoet Free version': window.mailpoet_version}
205
+ );
206
+ });
207
+
208
+ $('.mailpoet_premium_activate_link').on('click', function() {
209
+ MailPoet.trackEvent(
210
+ 'User has activated the Premium plugin from Settings',
211
+ {'MailPoet Free version': window.mailpoet_version}
212
+ );
213
+ });
214
+
215
  });
216
  });
217
  </script>
views/update.html CHANGED
@@ -2,13 +2,6 @@
2
 
3
  <% block content %>
4
 
5
- <style type="text/css">
6
- #mailpoet-changelog ul {
7
- list-style: disc;
8
- padding-left: 20px;
9
- }
10
- </style>
11
-
12
  <div class="wrap mailpoet-about-wrap">
13
  <h1><%= __('Greetings, humans.') %></h1>
14
 
@@ -24,7 +17,7 @@
24
  <a href="admin.php?page=mailpoet-update" class="nav-tab nav-tab-active"><%= __("What's New") %></a>
25
  </h2>
26
 
27
- <div id="mailpoet-changelog" class="feature-section one-col-left">
28
  <h2 class="mailpoet-feature-top"><%= __('List of Changes') %></h2>
29
  <% if changelog %>
30
  <% for item in changelog %>
@@ -44,7 +37,7 @@
44
  <hr>
45
 
46
  <% if(not settings.analytics.enabled) %>
47
- <div class="feature-section one-col">
48
  <h2><%= __('Do Your Part to Make MailPoet Better') %></h2>
49
  <div class="lead-description">
50
 
@@ -53,10 +46,10 @@
53
  <%= __('Yes, share my data anonymously.') %>
54
  </label>
55
  </div>
56
- <p><%= __("By sharing your data with us, you can help us understand what our users like (and don't like).") %>
57
  <%= __('We use it to prioritize and develop new plugin features.') %><br>
58
  <%= __('Share your data to help shape the future of MailPoet! [link]Read more.[/link]')
59
- |replaceLinkTags('http://docs.mailpoet.com/article/36-share-your-data', {'target' : '_blank'})
60
  |raw
61
  %>
62
  </div>
@@ -64,17 +57,17 @@
64
  <hr>
65
  <% endif %>
66
 
67
- <div class="feature-section one-col">
68
  <h2><%= __('Care to Give Your Opinion?') %></h2>
69
 
70
- <script type="text/javascript" charset="utf-8" src="http://static.polldaddy.com/p/9780744.js"></script>
71
- <noscript><a href="http://polldaddy.com/poll/9780744/">How likely is it that you would MailPoet to a friend or colleague?</a></noscript>
72
  </div>
73
 
74
  <hr>
75
 
76
- <div class="feature-section one-col">
77
- <a class="button button-primary" href="admin.php?page=mailpoet-newsletters"><%= __('Awesome! Now, take me to MailPoet') %> &rarr;</a>
78
  </div>
79
 
80
  </div>
2
 
3
  <% block content %>
4
 
 
 
 
 
 
 
 
5
  <div class="wrap mailpoet-about-wrap">
6
  <h1><%= __('Greetings, humans.') %></h1>
7
 
17
  <a href="admin.php?page=mailpoet-update" class="nav-tab nav-tab-active"><%= __("What's New") %></a>
18
  </h2>
19
 
20
+ <div id="mailpoet-changelog" class="feature-section one-col">
21
  <h2 class="mailpoet-feature-top"><%= __('List of Changes') %></h2>
22
  <% if changelog %>
23
  <% for item in changelog %>
37
  <hr>
38
 
39
  <% if(not settings.analytics.enabled) %>
40
+ <div class="feature-section one-col mailpoet_centered">
41
  <h2><%= __('Do Your Part to Make MailPoet Better') %></h2>
42
  <div class="lead-description">
43
 
46
  <%= __('Yes, share my data anonymously.') %>
47
  </label>
48
  </div>
49
+ <p class="top-space-triple"><%= __("By sharing your data with us, you can help us understand what our users like (and don't like).") %>
50
  <%= __('We use it to prioritize and develop new plugin features.') %><br>
51
  <%= __('Share your data to help shape the future of MailPoet! [link]Read more.[/link]')
52
+ |replaceLinkTags('http://beta.docs.mailpoet.com/article/130-sharing-your-data-with-us', {'target' : '_blank'})
53
  |raw
54
  %>
55
  </div>
57
  <hr>
58
  <% endif %>
59
 
60
+ <div class="feature-section one-col mailpoet_centered">
61
  <h2><%= __('Care to Give Your Opinion?') %></h2>
62
 
63
+ <script type="text/javascript" charset="utf-8" src="http://static.polldaddy.com/p/9792509.js"></script>
64
+ <noscript><a href="http://polldaddy.com/poll/9792509/">Did you ever have issues with the emails sent from your WordPress (ie password reset, new comment notifications, WooCommerce emails, etc.)?</a></noscript>
65
  </div>
66
 
67
  <hr>
68
 
69
+ <div class="feature-section one-col mailpoet_centered">
70
+ <a class="button button-primary go-to-plugin" href="admin.php?page=mailpoet-newsletters"><%= __('Awesome! Now, take me to MailPoet') %> &rarr;</a>
71
  </div>
72
 
73
  </div>
views/welcome.html CHANGED
@@ -2,22 +2,6 @@
2
 
3
  <% block content %>
4
 
5
- <style type="text/css">
6
- .videoWrapper {
7
- position: relative;
8
- padding-bottom: 56.25%; /* 16:9 */
9
- /*padding-top: 25px;*/
10
- height: 0;
11
- }
12
- .videoWrapper iframe {
13
- position: absolute;
14
- top: 0;
15
- left: 0;
16
- width: 100%;
17
- height: 100%;
18
- }
19
- </style>
20
-
21
  <div class="wrap mailpoet-about-wrap">
22
  <h1><%= __('Greetings, humans.') %></h1>
23
 
@@ -50,7 +34,7 @@
50
  </div>
51
  <div class="col">
52
  <h3><%= __('Sharing is Caring') %></h3>
53
- <p><%= __("By sharing your data <i>anonymously</i> with us, you can help us understand <i>how people use MailPoet</i> and <i>what sort of features they like and don't like</i>.") %> <a href="http://docs.mailpoet.com/article/36-share-your-data" target="_blank"><%= __('Find out more') %> &rarr;</a>
54
  <br><br>
55
  <label>
56
  <input type="checkbox" id="mailpoet_analytics_enabled" value="1"
@@ -83,9 +67,8 @@
83
 
84
  <hr>
85
 
86
- <div clas="feature-section one-col">
87
- <br>
88
- <p style="text-align: center"><a class="button button-primary" href="admin.php?page=mailpoet-newsletters"><%= __("Awesome! Now, take me to MailPoet") %> &rarr;</a></p>
89
  </div>
90
 
91
  </div>
2
 
3
  <% block content %>
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  <div class="wrap mailpoet-about-wrap">
6
  <h1><%= __('Greetings, humans.') %></h1>
7
 
34
  </div>
35
  <div class="col">
36
  <h3><%= __('Sharing is Caring') %></h3>
37
+ <p><%= __("By sharing your data <i>anonymously</i> with us, you can help us understand <i>how people use MailPoet</i> and <i>what sort of features they like and don't like</i>.") %> <a href="http://beta.docs.mailpoet.com/article/130-sharing-your-data-with-us" target="_blank"><%= __('Find out more') %> &rarr;</a>
38
  <br><br>
39
  <label>
40
  <input type="checkbox" id="mailpoet_analytics_enabled" value="1"
67
 
68
  <hr>
69
 
70
+ <div class="feature-section one-col mailpoet_centered">
71
+ <a class="button button-primary go-to-plugin" href="admin.php?page=mailpoet-newsletters"><%= __("Awesome! Now, take me to MailPoet") %> &rarr;</a>
 
72
  </div>
73
 
74
  </div>