MailPoet Newsletters (New) - Version 3.11.2

Version Description

  • 2018-10-09 =
  • Added: Linux cron option for sending emails;
  • Fixed: fatal error for admins who are not also subscribers;
  • Fixed: minor style fixes;
  • Fixed: added missing translation string;
  • Fixed: orphaned tasks cleared after subscribers deleted;
  • Fixed: minor styling issue on schedule page for Mac Chrome users.
Download this release

Release Info

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

Code changes from version 3.11.1 to 3.11.2

Files changed (51) hide show
  1. assets/css/{admin.86751c85.css → admin.90fe3283.css} +6 -3
  2. assets/css/manifest.json +1 -1
  3. assets/js/{admin.41cfe984.js → admin.eaab3da3.js} +1 -1
  4. assets/js/{admin_vendor.41cfe984.js → admin_vendor.eaab3da3.js} +1 -2
  5. assets/js/{form_editor.41cfe984.js → form_editor.eaab3da3.js} +0 -0
  6. assets/js/{mailpoet.41cfe984.js → mailpoet.eaab3da3.js} +0 -0
  7. assets/js/manifest.json +6 -6
  8. assets/js/{newsletter_editor.41cfe984.js → newsletter_editor.eaab3da3.js} +0 -0
  9. assets/js/{vendor.41cfe984.js → vendor.eaab3da3.js} +0 -0
  10. lang/mailpoet-ca.mo +0 -0
  11. lang/mailpoet-da_DK.mo +0 -0
  12. lang/mailpoet-de_DE.mo +0 -0
  13. lang/mailpoet-es_ES.mo +0 -0
  14. lang/mailpoet-fa_IR.mo +0 -0
  15. lang/mailpoet-fr_CA.mo +0 -0
  16. lang/mailpoet-fr_FR.mo +0 -0
  17. lang/mailpoet-it_IT.mo +0 -0
  18. lang/mailpoet-ja.mo +0 -0
  19. lang/mailpoet-nl_NL.mo +0 -0
  20. lang/mailpoet-pl_PL.mo +0 -0
  21. lang/mailpoet-pt_BR.mo +0 -0
  22. lang/mailpoet-pt_PT.mo +0 -0
  23. lang/mailpoet-ru_RU.mo +0 -0
  24. lang/mailpoet-sq.mo +0 -0
  25. lang/mailpoet-sv_SE.mo +0 -0
  26. lang/mailpoet-tr_TR.mo +0 -0
  27. lang/mailpoet-zh_CN.mo +0 -0
  28. lang/mailpoet.pot +63 -47
  29. lib/Config/Menu.php +5 -1
  30. lib/Cron/CronHelper.php +3 -3
  31. lib/Cron/CronTrigger.php +2 -1
  32. lib/Cron/Daemon.php +4 -89
  33. lib/Cron/DaemonHttpRunner.php +112 -0
  34. lib/Cron/Supervisor.php +1 -1
  35. lib/Cron/Triggers/MailPoet.php +1 -1
  36. lib/Cron/Workers/Scheduler.php +17 -0
  37. lib/Cron/Workers/SendingQueue/SendingQueue.php +5 -0
  38. lib/Models/ScheduledTask.php +12 -0
  39. lib/Newsletter/AutomatedLatestContent.php +26 -0
  40. lib/Newsletter/Scheduler/Scheduler.php +9 -0
  41. lib/Router/Endpoints/CronDaemon.php +3 -3
  42. mailpoet.php +2 -2
  43. readme.txt +9 -1
  44. vendor/autoload.php +1 -1
  45. vendor/composer/ClassLoader.php +1 -1
  46. vendor/composer/autoload_classmap.php +1 -0
  47. vendor/composer/autoload_real.php +7 -7
  48. vendor/composer/autoload_static.php +7 -6
  49. views/settings.html +10 -0
  50. views/settings/advanced.html +29 -0
  51. views/settings/mta.html +1 -1
assets/css/{admin.86751c85.css → admin.90fe3283.css} RENAMED
@@ -4447,13 +4447,16 @@ tr.introjs-showElement > th {
4447
  top: -3px;
4448
  left: 8px;
4449
  }
4450
- .mailpoet_in_app_announcement_background_videos {
 
4451
  text-align: center;
4452
  }
4453
- .mailpoet_in_app_announcement_background_videos h2 {
 
4454
  font-size: 28px;
4455
  }
4456
- .mailpoet_in_app_announcement_background_videos video {
 
4457
  margin-top: 20px;
4458
  }
4459
  @-moz-keyframes mailpoet_in_app_dot_pulse {
4447
  top: -3px;
4448
  left: 8px;
4449
  }
4450
+ .mailpoet_in_app_announcement_background_videos,
4451
+ .mailpoet_drag_and_drop_tutorial {
4452
  text-align: center;
4453
  }
4454
+ .mailpoet_in_app_announcement_background_videos h2,
4455
+ .mailpoet_drag_and_drop_tutorial h2 {
4456
  font-size: 28px;
4457
  }
4458
+ .mailpoet_in_app_announcement_background_videos video,
4459
+ .mailpoet_drag_and_drop_tutorial video {
4460
  margin-top: 20px;
4461
  }
4462
  @-moz-keyframes mailpoet_in_app_dot_pulse {
assets/css/manifest.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "admin-global.css": "admin-global.673373a1.css",
3
- "admin.css": "admin.86751c85.css",
4
  "importExport.css": "importExport.b3745466.css",
5
  "newsletter_editor.css": "newsletter_editor.4555a028.css",
6
  "public.css": "public.cae357df.css",
1
  {
2
  "admin-global.css": "admin-global.673373a1.css",
3
+ "admin.css": "admin.90fe3283.css",
4
  "importExport.css": "importExport.b3745466.css",
5
  "newsletter_editor.css": "newsletter_editor.4555a028.css",
6
  "public.css": "public.cae357df.css",
assets/js/{admin.41cfe984.js → admin.eaab3da3.js} RENAMED
@@ -18840,7 +18840,7 @@ var DateText = _react2.default.createClass({
18840
 
18841
  return _react2.default.createElement('input', _extends({
18842
  type: 'text',
18843
- size: '10',
18844
  name: this.getFieldName(),
18845
  value: this.getDisplayDate(this.props.value),
18846
  readOnly: true,
18840
 
18841
  return _react2.default.createElement('input', _extends({
18842
  type: 'text',
18843
+ size: '30',
18844
  name: this.getFieldName(),
18845
  value: this.getDisplayDate(this.props.value),
18846
  readOnly: true,
assets/js/{admin_vendor.41cfe984.js → admin_vendor.eaab3da3.js} RENAMED
@@ -67208,8 +67208,7 @@ var displayTutorial = function displayTutorial() {
67208
  return;
67209
  }
67210
  _mailpoet2.default.Modal.popup({
67211
- title: _mailpoet2.default.I18n.t('tutorialVideoTitle'),
67212
- template: '<video style="height:640px;" src="' + window.config.dragDemoUrl + '" controls autoplay></video>',
67213
  onCancel: function onCancel() {
67214
  _mailpoet2.default.Ajax.post({
67215
  api_version: window.mailpoet_api_version,
67208
  return;
67209
  }
67210
  _mailpoet2.default.Modal.popup({
67211
+ template: '<div class="mailpoet_drag_and_drop_tutorial"><h2>' + _mailpoet2.default.I18n.t('tutorialVideoTitle') + '</h2><video style="height:640px;" src="' + window.config.dragDemoUrl + '" controls autoplay></video></div>',
 
67212
  onCancel: function onCancel() {
67213
  _mailpoet2.default.Ajax.post({
67214
  api_version: window.mailpoet_api_version,
assets/js/{form_editor.41cfe984.js → form_editor.eaab3da3.js} RENAMED
File without changes
assets/js/{mailpoet.41cfe984.js → mailpoet.eaab3da3.js} RENAMED
File without changes
assets/js/manifest.json CHANGED
@@ -1,10 +1,10 @@
1
  {
2
  "mp2migrator.js": "mp2migrator.8768b2f6.js",
3
  "public.js": "public.8a5f8230.js",
4
- "admin.js": "admin.41cfe984.js",
5
- "admin_vendor.js": "admin_vendor.41cfe984.js",
6
- "form_editor.js": "form_editor.41cfe984.js",
7
- "mailpoet.js": "mailpoet.41cfe984.js",
8
- "newsletter_editor.js": "newsletter_editor.41cfe984.js",
9
- "vendor.js": "vendor.41cfe984.js"
10
  }
1
  {
2
  "mp2migrator.js": "mp2migrator.8768b2f6.js",
3
  "public.js": "public.8a5f8230.js",
4
+ "admin.js": "admin.eaab3da3.js",
5
+ "admin_vendor.js": "admin_vendor.eaab3da3.js",
6
+ "form_editor.js": "form_editor.eaab3da3.js",
7
+ "mailpoet.js": "mailpoet.eaab3da3.js",
8
+ "newsletter_editor.js": "newsletter_editor.eaab3da3.js",
9
+ "vendor.js": "vendor.eaab3da3.js"
10
  }
assets/js/{newsletter_editor.41cfe984.js → newsletter_editor.eaab3da3.js} RENAMED
File without changes
assets/js/{vendor.41cfe984.js → vendor.eaab3da3.js} RENAMED
File without changes
lang/mailpoet-ca.mo CHANGED
Binary file
lang/mailpoet-da_DK.mo CHANGED
Binary file
lang/mailpoet-de_DE.mo CHANGED
Binary file
lang/mailpoet-es_ES.mo CHANGED
Binary file
lang/mailpoet-fa_IR.mo CHANGED
Binary file
lang/mailpoet-fr_CA.mo CHANGED
Binary file
lang/mailpoet-fr_FR.mo CHANGED
Binary file
lang/mailpoet-it_IT.mo CHANGED
Binary file
lang/mailpoet-ja.mo CHANGED
Binary file
lang/mailpoet-nl_NL.mo CHANGED
Binary file
lang/mailpoet-pl_PL.mo CHANGED
Binary file
lang/mailpoet-pt_BR.mo CHANGED
Binary file
lang/mailpoet-pt_PT.mo CHANGED
Binary file
lang/mailpoet-ru_RU.mo CHANGED
Binary file
lang/mailpoet-sq.mo CHANGED
Binary file
lang/mailpoet-sv_SE.mo CHANGED
Binary file
lang/mailpoet-tr_TR.mo CHANGED
Binary file
lang/mailpoet-zh_CN.mo CHANGED
Binary file
lang/mailpoet.pot CHANGED
@@ -4,7 +4,7 @@ msgid ""
4
  msgstr ""
5
  "Project-Id-Version: \n"
6
  "Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
7
- "POT-Creation-Date: 2018-10-02 11:09:12+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -305,7 +305,7 @@ msgstr ""
305
  msgid "Manage segments"
306
  msgstr ""
307
 
308
- #: lib/Config/Capabilities.php:67 lib/Config/Menu.php:699
309
  #: lib/Config/PrivacyPolicy.php:11 views/premium.html:41
310
  msgid "MailPoet"
311
  msgstr ""
@@ -478,72 +478,72 @@ msgstr ""
478
  msgid "Migration"
479
  msgstr ""
480
 
481
- #: lib/Config/Menu.php:564
482
  msgid "In any WordPress role"
483
  msgstr ""
484
 
485
- #: lib/Config/Menu.php:583
486
  msgid "WooCommerce"
487
  msgstr ""
488
 
489
- #: lib/Config/Menu.php:584
490
  msgid ""
491
  "Automatically send an email when there is a new WooCommerce product, order "
492
  "and some other action takes place."
493
  msgstr ""
494
 
495
- #: lib/Config/Menu.php:588
496
  msgid "Abandoned Shopping Cart"
497
  msgstr ""
498
 
499
- #: lib/Config/Menu.php:589
500
  msgid ""
501
  "Send an email to logged-in visitors who have items in their shopping carts "
502
  "but left your website without checking out. Can convert up to 5% of "
503
  "abandoned carts."
504
  msgstr ""
505
 
506
- #: lib/Config/Menu.php:592 lib/Config/Menu.php:611
507
  msgid "Must-have"
508
  msgstr ""
509
 
510
- #: lib/Config/Menu.php:598
511
  msgid "Big Spender"
512
  msgstr ""
513
 
514
- #: lib/Config/Menu.php:599
515
  msgid ""
516
  "Let MailPoet send an email to customers who have spent a certain amount to "
517
  "thank them, possibly with a coupon."
518
  msgstr ""
519
 
520
- #: lib/Config/Menu.php:602
521
  msgid "Smart to have"
522
  msgstr ""
523
 
524
- #: lib/Config/Menu.php:608
525
  msgid "First Purchase"
526
  msgstr ""
527
 
528
- #: lib/Config/Menu.php:609
529
  msgid "Let MailPoet send an email to customers who make their first purchase."
530
  msgstr ""
531
 
532
- #: lib/Config/Menu.php:617
533
  msgid "Purchased In This Category"
534
  msgstr ""
535
 
536
- #: lib/Config/Menu.php:618
537
  msgid ""
538
  "Let MailPoet send an email to customers who purchase a product from a "
539
  "specific category."
540
  msgstr ""
541
 
542
- #: lib/Config/Menu.php:623
543
  msgid "Purchased This Product"
544
  msgstr ""
545
 
546
- #: lib/Config/Menu.php:624
547
  msgid "Let MailPoet send an email to customers who purchase a specific product."
548
  msgstr ""
549
 
@@ -1183,11 +1183,11 @@ msgstr ""
1183
  msgid "Maximum execution time has been reached."
1184
  msgstr ""
1185
 
1186
- #: lib/Cron/Daemon.php:40
1187
  msgid "Invalid or missing request data."
1188
  msgstr ""
1189
 
1190
- #: lib/Cron/Daemon.php:43
1191
  msgid "Daemon does not exist."
1192
  msgstr ""
1193
 
@@ -1832,8 +1832,8 @@ msgstr ""
1832
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:151
1833
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:177
1834
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:239
1835
- #: views/premium.html:62 views/premium.html:63 views/settings/advanced.html:124
1836
- #: views/settings/advanced.html:164 views/settings/advanced.html:204
1837
  #: views/settings/mta.html:539 views/settings/mta.html:593
1838
  #: views/settings/signup.html:46
1839
  #: views/subscribers/importExport/import/step2.html:67
@@ -2212,8 +2212,8 @@ msgstr ""
2212
  #: views/newsletter/templates/blocks/automatedLatestContentLayout/settings.hbs:293
2213
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:79
2214
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:233
2215
- #: views/premium.html:56 views/settings/advanced.html:112
2216
- #: views/settings/advanced.html:153 views/settings/advanced.html:193
2217
  #: views/settings/mta.html:582 views/settings/signup.html:34
2218
  #: views/subscribers/importExport/import/step2.html:63
2219
  msgid "Yes"
@@ -4679,83 +4679,95 @@ msgstr ""
4679
  msgid "MailPoet's own script. Doesn't work with [link]these hosts[/link]."
4680
  msgstr ""
4681
 
4682
- #: views/settings/advanced.html:73
 
 
 
 
 
 
 
 
 
 
 
 
4683
  msgid "Roles and capabilities"
4684
  msgstr ""
4685
 
4686
- #: views/settings/advanced.html:75
4687
  msgid "Manage which WordPress roles access which features of MailPoet."
4688
  msgstr ""
4689
 
4690
- #: views/settings/advanced.html:81
4691
  msgid "Manage using the Members plugin"
4692
  msgstr ""
4693
 
4694
- #: views/settings/advanced.html:84
4695
  msgid "Install the plugin [link]Members[/link] (free) to manage permissions."
4696
  msgstr ""
4697
 
4698
- #: views/settings/advanced.html:95
4699
  msgid "Open and click tracking"
4700
  msgstr ""
4701
 
4702
- #: views/settings/advanced.html:98
4703
  msgid "Enable or disable open and click tracking."
4704
  msgstr ""
4705
 
4706
- #: views/settings/advanced.html:133
4707
  msgid "Share anonymous data"
4708
  msgstr ""
4709
 
4710
- #: views/settings/advanced.html:136
4711
  msgid ""
4712
  "Share anonymous data and help us improve the plugin. We appreciate your "
4713
  "help!"
4714
  msgstr ""
4715
 
4716
- #: views/settings/advanced.html:173
4717
  msgid "Enable reCAPTCHA"
4718
  msgstr ""
4719
 
4720
- #: views/settings/advanced.html:176
4721
  msgid "Use reCAPTCHA to protect MailPoet subscription forms."
4722
  msgstr ""
4723
 
4724
- #: views/settings/advanced.html:180
4725
  msgid "Sign up for an API key pair here."
4726
  msgstr ""
4727
 
4728
- #: views/settings/advanced.html:212
4729
  msgid "Your reCAPTCHA Site Key"
4730
  msgstr ""
4731
 
4732
- #: views/settings/advanced.html:220
4733
  msgid "Your reCAPTCHA Secret Key"
4734
  msgstr ""
4735
 
4736
- #: views/settings/advanced.html:225
4737
  msgid "Please fill the reCAPTCHA keys."
4738
  msgstr ""
4739
 
4740
- #: views/settings/advanced.html:233
4741
  msgid "Reinstall from scratch"
4742
  msgstr ""
4743
 
4744
- #: views/settings/advanced.html:235
4745
  msgid ""
4746
  "Want to start from the beginning? This will completely delete MailPoet and "
4747
  "reinstall it from scratch. Remember: you will lose all of your data!"
4748
  msgstr ""
4749
 
4750
- #: views/settings/advanced.html:243
4751
  msgid "Reinstall now..."
4752
  msgstr ""
4753
 
4754
- #: views/settings/advanced.html:250
4755
  msgid "Logging"
4756
  msgstr ""
4757
 
4758
- #: views/settings/advanced.html:252
4759
  msgid "Enables logging for diagnostics of plugin behavior."
4760
  msgstr ""
4761
 
@@ -4938,6 +4950,10 @@ msgstr ""
4938
  msgid "Get a free key"
4939
  msgstr ""
4940
 
 
 
 
 
4941
  #: views/settings/mta.html:104
4942
  msgid "[link]enter your key[/link]"
4943
  msgstr ""
@@ -5280,7 +5296,7 @@ msgstr ""
5280
  msgid "Settings saved"
5281
  msgstr ""
5282
 
5283
- #: views/settings.html:187
5284
  msgid ""
5285
  "Are you sure? All of your MailPoet data will be permanently erased "
5286
  "(newsletters, statistics, subscribers, etc.)."
@@ -6039,22 +6055,22 @@ msgid "Got it!"
6039
  msgstr ""
6040
 
6041
  #: views/settings/advanced.html:13 views/settings/advanced.html:37
6042
- #: views/settings/advanced.html:140
6043
  msgctxt "support article link label"
6044
  msgid "Read more."
6045
  msgstr ""
6046
 
6047
- #: views/settings/advanced.html:262
6048
  msgctxt "In settings: \"Logging: Everything\""
6049
  msgid "Everything"
6050
  msgstr ""
6051
 
6052
- #: views/settings/advanced.html:268
6053
  msgctxt "In settings: \"Logging: Errors only\""
6054
  msgid "Errors only"
6055
  msgstr ""
6056
 
6057
- #: views/settings/advanced.html:274
6058
  msgctxt "In settings: \"Logging: Nothing\""
6059
  msgid "Nothing"
6060
  msgstr ""
4
  msgstr ""
5
  "Project-Id-Version: \n"
6
  "Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
7
+ "POT-Creation-Date: 2018-10-09 11:29:59+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
305
  msgid "Manage segments"
306
  msgstr ""
307
 
308
+ #: lib/Config/Capabilities.php:67 lib/Config/Menu.php:703
309
  #: lib/Config/PrivacyPolicy.php:11 views/premium.html:41
310
  msgid "MailPoet"
311
  msgstr ""
478
  msgid "Migration"
479
  msgstr ""
480
 
481
+ #: lib/Config/Menu.php:566
482
  msgid "In any WordPress role"
483
  msgstr ""
484
 
485
+ #: lib/Config/Menu.php:585
486
  msgid "WooCommerce"
487
  msgstr ""
488
 
489
+ #: lib/Config/Menu.php:586
490
  msgid ""
491
  "Automatically send an email when there is a new WooCommerce product, order "
492
  "and some other action takes place."
493
  msgstr ""
494
 
495
+ #: lib/Config/Menu.php:590
496
  msgid "Abandoned Shopping Cart"
497
  msgstr ""
498
 
499
+ #: lib/Config/Menu.php:591
500
  msgid ""
501
  "Send an email to logged-in visitors who have items in their shopping carts "
502
  "but left your website without checking out. Can convert up to 5% of "
503
  "abandoned carts."
504
  msgstr ""
505
 
506
+ #: lib/Config/Menu.php:594 lib/Config/Menu.php:613
507
  msgid "Must-have"
508
  msgstr ""
509
 
510
+ #: lib/Config/Menu.php:600
511
  msgid "Big Spender"
512
  msgstr ""
513
 
514
+ #: lib/Config/Menu.php:601
515
  msgid ""
516
  "Let MailPoet send an email to customers who have spent a certain amount to "
517
  "thank them, possibly with a coupon."
518
  msgstr ""
519
 
520
+ #: lib/Config/Menu.php:604
521
  msgid "Smart to have"
522
  msgstr ""
523
 
524
+ #: lib/Config/Menu.php:610
525
  msgid "First Purchase"
526
  msgstr ""
527
 
528
+ #: lib/Config/Menu.php:611
529
  msgid "Let MailPoet send an email to customers who make their first purchase."
530
  msgstr ""
531
 
532
+ #: lib/Config/Menu.php:619
533
  msgid "Purchased In This Category"
534
  msgstr ""
535
 
536
+ #: lib/Config/Menu.php:620
537
  msgid ""
538
  "Let MailPoet send an email to customers who purchase a product from a "
539
  "specific category."
540
  msgstr ""
541
 
542
+ #: lib/Config/Menu.php:625
543
  msgid "Purchased This Product"
544
  msgstr ""
545
 
546
+ #: lib/Config/Menu.php:626
547
  msgid "Let MailPoet send an email to customers who purchase a specific product."
548
  msgstr ""
549
 
1183
  msgid "Maximum execution time has been reached."
1184
  msgstr ""
1185
 
1186
+ #: lib/Cron/DaemonHttpRunner.php:41
1187
  msgid "Invalid or missing request data."
1188
  msgstr ""
1189
 
1190
+ #: lib/Cron/DaemonHttpRunner.php:44
1191
  msgid "Daemon does not exist."
1192
  msgstr ""
1193
 
1832
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:151
1833
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:177
1834
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:239
1835
+ #: views/premium.html:62 views/premium.html:63 views/settings/advanced.html:153
1836
+ #: views/settings/advanced.html:193 views/settings/advanced.html:233
1837
  #: views/settings/mta.html:539 views/settings/mta.html:593
1838
  #: views/settings/signup.html:46
1839
  #: views/subscribers/importExport/import/step2.html:67
2212
  #: views/newsletter/templates/blocks/automatedLatestContentLayout/settings.hbs:293
2213
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:79
2214
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:233
2215
+ #: views/premium.html:56 views/settings/advanced.html:141
2216
+ #: views/settings/advanced.html:182 views/settings/advanced.html:222
2217
  #: views/settings/mta.html:582 views/settings/signup.html:34
2218
  #: views/subscribers/importExport/import/step2.html:63
2219
  msgid "Yes"
4679
  msgid "MailPoet's own script. Doesn't work with [link]these hosts[/link]."
4680
  msgstr ""
4681
 
4682
+ #: views/settings/advanced.html:77
4683
+ msgid "Server side cron (Linux cron)"
4684
+ msgstr ""
4685
+
4686
+ #: views/settings/advanced.html:83
4687
+ msgid "To use this option please add this command to your crontab:"
4688
+ msgstr ""
4689
+
4690
+ #: views/settings/advanced.html:90
4691
+ msgid "With the frequency of running it every minute:"
4692
+ msgstr ""
4693
+
4694
+ #: views/settings/advanced.html:102
4695
  msgid "Roles and capabilities"
4696
  msgstr ""
4697
 
4698
+ #: views/settings/advanced.html:104
4699
  msgid "Manage which WordPress roles access which features of MailPoet."
4700
  msgstr ""
4701
 
4702
+ #: views/settings/advanced.html:110
4703
  msgid "Manage using the Members plugin"
4704
  msgstr ""
4705
 
4706
+ #: views/settings/advanced.html:113
4707
  msgid "Install the plugin [link]Members[/link] (free) to manage permissions."
4708
  msgstr ""
4709
 
4710
+ #: views/settings/advanced.html:124
4711
  msgid "Open and click tracking"
4712
  msgstr ""
4713
 
4714
+ #: views/settings/advanced.html:127
4715
  msgid "Enable or disable open and click tracking."
4716
  msgstr ""
4717
 
4718
+ #: views/settings/advanced.html:162
4719
  msgid "Share anonymous data"
4720
  msgstr ""
4721
 
4722
+ #: views/settings/advanced.html:165
4723
  msgid ""
4724
  "Share anonymous data and help us improve the plugin. We appreciate your "
4725
  "help!"
4726
  msgstr ""
4727
 
4728
+ #: views/settings/advanced.html:202
4729
  msgid "Enable reCAPTCHA"
4730
  msgstr ""
4731
 
4732
+ #: views/settings/advanced.html:205
4733
  msgid "Use reCAPTCHA to protect MailPoet subscription forms."
4734
  msgstr ""
4735
 
4736
+ #: views/settings/advanced.html:209
4737
  msgid "Sign up for an API key pair here."
4738
  msgstr ""
4739
 
4740
+ #: views/settings/advanced.html:241
4741
  msgid "Your reCAPTCHA Site Key"
4742
  msgstr ""
4743
 
4744
+ #: views/settings/advanced.html:249
4745
  msgid "Your reCAPTCHA Secret Key"
4746
  msgstr ""
4747
 
4748
+ #: views/settings/advanced.html:254
4749
  msgid "Please fill the reCAPTCHA keys."
4750
  msgstr ""
4751
 
4752
+ #: views/settings/advanced.html:262
4753
  msgid "Reinstall from scratch"
4754
  msgstr ""
4755
 
4756
+ #: views/settings/advanced.html:264
4757
  msgid ""
4758
  "Want to start from the beginning? This will completely delete MailPoet and "
4759
  "reinstall it from scratch. Remember: you will lose all of your data!"
4760
  msgstr ""
4761
 
4762
+ #: views/settings/advanced.html:272
4763
  msgid "Reinstall now..."
4764
  msgstr ""
4765
 
4766
+ #: views/settings/advanced.html:279
4767
  msgid "Logging"
4768
  msgstr ""
4769
 
4770
+ #: views/settings/advanced.html:281
4771
  msgid "Enables logging for diagnostics of plugin behavior."
4772
  msgstr ""
4773
 
4950
  msgid "Get a free key"
4951
  msgstr ""
4952
 
4953
+ #: views/settings/mta.html:102
4954
+ msgid "or"
4955
+ msgstr ""
4956
+
4957
  #: views/settings/mta.html:104
4958
  msgid "[link]enter your key[/link]"
4959
  msgstr ""
5296
  msgid "Settings saved"
5297
  msgstr ""
5298
 
5299
+ #: views/settings.html:197
5300
  msgid ""
5301
  "Are you sure? All of your MailPoet data will be permanently erased "
5302
  "(newsletters, statistics, subscribers, etc.)."
6055
  msgstr ""
6056
 
6057
  #: views/settings/advanced.html:13 views/settings/advanced.html:37
6058
+ #: views/settings/advanced.html:169
6059
  msgctxt "support article link label"
6060
  msgid "Read more."
6061
  msgstr ""
6062
 
6063
+ #: views/settings/advanced.html:291
6064
  msgctxt "In settings: \"Logging: Everything\""
6065
  msgid "Everything"
6066
  msgstr ""
6067
 
6068
+ #: views/settings/advanced.html:297
6069
  msgctxt "In settings: \"Logging: Errors only\""
6070
  msgid "Errors only"
6071
  msgstr ""
6072
 
6073
+ #: views/settings/advanced.html:303
6074
  msgctxt "In settings: \"Logging: Nothing\""
6075
  msgid "Nothing"
6076
  msgstr ""
lib/Config/Menu.php CHANGED
@@ -419,6 +419,8 @@ class Menu {
419
  'pages' => Pages::getAll(),
420
  'flags' => $flags,
421
  'current_user' => wp_get_current_user(),
 
 
422
  'hosts' => array(
423
  'web' => Hosts::getWebHosts(),
424
  'smtp' => Hosts::getSMTPHosts()
@@ -636,10 +638,12 @@ class Menu {
636
  }
637
 
638
  function newletterEditor() {
 
 
639
  $data = array(
640
  'shortcodes' => ShortcodesHelper::getShortcodes(),
641
  'settings' => Setting::getAll(),
642
- 'current_wp_user' => array_merge(Subscriber::getCurrentWPUser()->asArray(), wp_get_current_user()->to_array()),
643
  'sub_menu' => self::MAIN_PAGE_SLUG,
644
  'mss_active' => Bridge::isMPSendingServiceEnabled()
645
  );
419
  'pages' => Pages::getAll(),
420
  'flags' => $flags,
421
  'current_user' => wp_get_current_user(),
422
+ 'linux_cron_path' => dirname(dirname(__DIR__)),
423
+ 'ABSPATH' => ABSPATH,
424
  'hosts' => array(
425
  'web' => Hosts::getWebHosts(),
426
  'smtp' => Hosts::getSMTPHosts()
638
  }
639
 
640
  function newletterEditor() {
641
+ $subscriber = Subscriber::getCurrentWPUser();
642
+ $subscriber_data = $subscriber ? $subscriber->asArray() : [];
643
  $data = array(
644
  'shortcodes' => ShortcodesHelper::getShortcodes(),
645
  'settings' => Setting::getAll(),
646
+ 'current_wp_user' => array_merge($subscriber_data, wp_get_current_user()->to_array()),
647
  'sub_menu' => self::MAIN_PAGE_SLUG,
648
  'mss_active' => Bridge::isMPSendingServiceEnabled()
649
  );
lib/Cron/CronHelper.php CHANGED
@@ -83,12 +83,12 @@ class CronHelper {
83
  $result = self::queryCronUrl($url);
84
  if(is_wp_error($result)) return $result->get_error_message();
85
  $response = WPFunctions::wpRemoteRetrieveBody($result);
86
- $response = substr(trim($response), -strlen(Daemon::PING_SUCCESS_RESPONSE)) === Daemon::PING_SUCCESS_RESPONSE ?
87
- Daemon::PING_SUCCESS_RESPONSE :
88
  $response;
89
  return (!$validate_response) ?
90
  $response :
91
- $response === Daemon::PING_SUCCESS_RESPONSE;
92
  }
93
 
94
  static function accessDaemon($token) {
83
  $result = self::queryCronUrl($url);
84
  if(is_wp_error($result)) return $result->get_error_message();
85
  $response = WPFunctions::wpRemoteRetrieveBody($result);
86
+ $response = substr(trim($response), -strlen(DaemonHttpRunner::PING_SUCCESS_RESPONSE)) === DaemonHttpRunner::PING_SUCCESS_RESPONSE ?
87
+ DaemonHttpRunner::PING_SUCCESS_RESPONSE :
88
  $response;
89
  return (!$validate_response) ?
90
  $response :
91
+ $response === DaemonHttpRunner::PING_SUCCESS_RESPONSE;
92
  }
93
 
94
  static function accessDaemon($token) {
lib/Cron/CronTrigger.php CHANGED
@@ -10,6 +10,7 @@ class CronTrigger {
10
  public static $available_methods = array(
11
  'mailpoet' => 'MailPoet',
12
  'wordpress' => 'WordPress',
 
13
  'none' => 'Disabled'
14
  );
15
  const DEFAULT_METHOD = 'WordPress';
@@ -37,4 +38,4 @@ class CronTrigger {
37
  static function getCurrentMethod() {
38
  return Setting::getValue(self::SETTING_NAME . '.method');
39
  }
40
- }
10
  public static $available_methods = array(
11
  'mailpoet' => 'MailPoet',
12
  'wordpress' => 'WordPress',
13
+ 'linux_cron' => 'Linux Cron',
14
  'none' => 'Disabled'
15
  );
16
  const DEFAULT_METHOD = 'WordPress';
38
  static function getCurrentMethod() {
39
  return Setting::getValue(self::SETTING_NAME . '.method');
40
  }
41
+ }
lib/Cron/Daemon.php CHANGED
@@ -12,50 +12,15 @@ if(!defined('ABSPATH')) exit;
12
  require_once(ABSPATH . 'wp-includes/pluggable.php');
13
 
14
  class Daemon {
15
- public $daemon;
16
- public $request_data;
17
  public $timer;
18
 
19
- const PING_SUCCESS_RESPONSE = 'pong';
20
-
21
- function __construct($request_data = false) {
22
- $this->request_data = $request_data;
23
- $this->daemon = CronHelper::getDaemon();
24
- $this->token = CronHelper::createToken();
25
  $this->timer = microtime(true);
26
  }
27
 
28
- function ping() {
29
- $this->addCacheHeaders();
30
- $this->terminateRequest(self::PING_SUCCESS_RESPONSE);
31
- }
32
-
33
- function run() {
34
- ignore_user_abort(true);
35
- if(strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
36
- set_time_limit(0);
37
- }
38
- $this->addCacheHeaders();
39
- if(!$this->request_data) {
40
- $error = __('Invalid or missing request data.', 'mailpoet');
41
- } else {
42
- if(!$this->daemon) {
43
- $error = __('Daemon does not exist.', 'mailpoet');
44
- } else {
45
- if(!isset($this->request_data['token']) ||
46
- $this->request_data['token'] !== $this->daemon['token']
47
- ) {
48
- $error = 'Invalid or missing token.';
49
- }
50
- }
51
- }
52
- if(!empty($error)) {
53
- return $this->abortWithError($error);
54
- }
55
- $daemon = $this->daemon;
56
- $daemon['token'] = $this->token;
57
- $daemon['run_started_at'] = time();
58
- CronHelper::saveDaemon($daemon);
59
  try {
60
  $this->executeMigrationWorker();
61
  $this->executeScheduleWorker();
@@ -68,22 +33,6 @@ class Daemon {
68
  }
69
  // Log successful execution
70
  CronHelper::saveDaemonRunCompleted(time());
71
- // if workers took less time to execute than the daemon execution limit,
72
- // pause daemon execution to ensure that daemon runs only once every X seconds
73
- $elapsed_time = microtime(true) - $this->timer;
74
- if($elapsed_time < CronHelper::DAEMON_EXECUTION_LIMIT) {
75
- $this->pauseExecution(CronHelper::DAEMON_EXECUTION_LIMIT - $elapsed_time);
76
- }
77
- // after each execution, re-read daemon data in case it changed
78
- $daemon = CronHelper::getDaemon();
79
- if($this->shouldTerminateExecution($daemon)) {
80
- return $this->terminateRequest();
81
- }
82
- return $this->callSelf();
83
- }
84
-
85
- function pauseExecution($pause_time) {
86
- return sleep($pause_time);
87
  }
88
 
89
  function executeScheduleWorker() {
@@ -116,38 +65,4 @@ class Daemon {
116
  return $migration->process();
117
  }
118
 
119
- function callSelf() {
120
- CronHelper::accessDaemon($this->token);
121
- return $this->terminateRequest();
122
- }
123
-
124
- function abortWithError($message) {
125
- status_header(404, $message);
126
- exit;
127
- }
128
-
129
- function terminateRequest($message = false) {
130
- die($message);
131
- }
132
-
133
- /**
134
- * @return boolean
135
- */
136
- private function shouldTerminateExecution(array $daemon = null) {
137
- return !$daemon ||
138
- $daemon['token'] !== $this->token ||
139
- (isset($daemon['status']) && $daemon['status'] !== CronHelper::DAEMON_STATUS_ACTIVE);
140
- }
141
-
142
- private function addCacheHeaders() {
143
- if(headers_sent()) {
144
- return;
145
- }
146
- // Common Cache Control header. Should be respected by cache proxies and CDNs.
147
- header('Cache-Control: no-cache');
148
- // Mark as blacklisted for SG Optimizer for sites hosted on SiteGround.
149
- header('X-Cache-Enabled: False');
150
- // Set caching header for LiteSpeed server.
151
- header('X-LiteSpeed-Cache-Control: no-cache');
152
- }
153
  }
12
  require_once(ABSPATH . 'wp-includes/pluggable.php');
13
 
14
  class Daemon {
 
 
15
  public $timer;
16
 
17
+ function __construct() {
 
 
 
 
 
18
  $this->timer = microtime(true);
19
  }
20
 
21
+ function run($settings_daemon_data) {
22
+ $settings_daemon_data['run_started_at'] = time();
23
+ CronHelper::saveDaemon($settings_daemon_data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  try {
25
  $this->executeMigrationWorker();
26
  $this->executeScheduleWorker();
33
  }
34
  // Log successful execution
35
  CronHelper::saveDaemonRunCompleted(time());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
 
38
  function executeScheduleWorker() {
65
  return $migration->process();
66
  }
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  }
lib/Cron/DaemonHttpRunner.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace MailPoet\Cron;
3
+
4
+ if(!defined('ABSPATH')) exit;
5
+ require_once(ABSPATH . 'wp-includes/pluggable.php');
6
+
7
+ class DaemonHttpRunner {
8
+ public $settings_daemon_data;
9
+ public $request_data;
10
+ public $timer;
11
+ public $token;
12
+
13
+ /** @var Daemon */
14
+ private $daemon;
15
+
16
+ const PING_SUCCESS_RESPONSE = 'pong';
17
+
18
+ function __construct($request_data = false, $daemon = null) {
19
+ $this->request_data = $request_data;
20
+ $this->settings_daemon_data = CronHelper::getDaemon();
21
+ $this->token = CronHelper::createToken();
22
+ $this->timer = microtime(true);
23
+ $this->daemon = $daemon;
24
+ if(!$daemon) {
25
+ $this->daemon = new Daemon($this->settings_daemon_data);
26
+ }
27
+ }
28
+
29
+ function ping() {
30
+ $this->addCacheHeaders();
31
+ $this->terminateRequest(self::PING_SUCCESS_RESPONSE);
32
+ }
33
+
34
+ function run() {
35
+ ignore_user_abort(true);
36
+ if(strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
37
+ set_time_limit(0);
38
+ }
39
+ $this->addCacheHeaders();
40
+ if(!$this->request_data) {
41
+ $error = __('Invalid or missing request data.', 'mailpoet');
42
+ } else {
43
+ if(!$this->settings_daemon_data) {
44
+ $error = __('Daemon does not exist.', 'mailpoet');
45
+ } else {
46
+ if(!isset($this->request_data['token']) ||
47
+ $this->request_data['token'] !== $this->settings_daemon_data['token']
48
+ ) {
49
+ $error = 'Invalid or missing token.';
50
+ }
51
+ }
52
+ }
53
+ if(!empty($error)) {
54
+ return $this->abortWithError($error);
55
+ }
56
+ $this->settings_daemon_data['token'] = $this->token;
57
+ $this->daemon->run($this->settings_daemon_data);
58
+ // if workers took less time to execute than the daemon execution limit,
59
+ // pause daemon execution to ensure that daemon runs only once every X seconds
60
+ $elapsed_time = microtime(true) - $this->timer;
61
+ if($elapsed_time < CronHelper::DAEMON_EXECUTION_LIMIT) {
62
+ $this->pauseExecution(CronHelper::DAEMON_EXECUTION_LIMIT - $elapsed_time);
63
+ }
64
+ // after each execution, re-read daemon data in case it changed
65
+ $settings_daemon_data = CronHelper::getDaemon();
66
+ if($this->shouldTerminateExecution($settings_daemon_data)) {
67
+ return $this->terminateRequest();
68
+ }
69
+ return $this->callSelf();
70
+ }
71
+
72
+ function pauseExecution($pause_time) {
73
+ return sleep($pause_time);
74
+ }
75
+
76
+ function callSelf() {
77
+ CronHelper::accessDaemon($this->token);
78
+ $this->terminateRequest();
79
+ }
80
+
81
+ function abortWithError($message) {
82
+ status_header(404, $message);
83
+ exit;
84
+ }
85
+
86
+ function terminateRequest($message = false) {
87
+ die($message);
88
+ }
89
+
90
+ /**
91
+ * @param array|null $settings_daemon_data
92
+ *
93
+ * @return boolean
94
+ */
95
+ private function shouldTerminateExecution(array $settings_daemon_data = null) {
96
+ return !$settings_daemon_data ||
97
+ $settings_daemon_data['token'] !== $this->token ||
98
+ (isset($settings_daemon_data['status']) && $settings_daemon_data['status'] !== CronHelper::DAEMON_STATUS_ACTIVE);
99
+ }
100
+
101
+ private function addCacheHeaders() {
102
+ if(headers_sent()) {
103
+ return;
104
+ }
105
+ // Common Cache Control header. Should be respected by cache proxies and CDNs.
106
+ header('Cache-Control: no-cache');
107
+ // Mark as blacklisted for SG Optimizer for sites hosted on SiteGround.
108
+ header('X-Cache-Enabled: False');
109
+ // Set caching header for LiteSpeed server.
110
+ header('X-LiteSpeed-Cache-Control: no-cache');
111
+ }
112
+ }
lib/Cron/Supervisor.php CHANGED
@@ -39,4 +39,4 @@ class Supervisor {
39
  }
40
  return $daemon;
41
  }
42
- }
39
  }
40
  return $daemon;
41
  }
42
+ }
lib/Cron/Triggers/MailPoet.php CHANGED
@@ -10,4 +10,4 @@ class MailPoet {
10
  $supervisor = new Supervisor();
11
  return $supervisor->checkDaemon();
12
  }
13
- }
10
  $supervisor = new Supervisor();
11
  return $supervisor->checkDaemon();
12
  }
13
+ }
lib/Cron/Workers/Scheduler.php CHANGED
@@ -4,6 +4,7 @@ namespace MailPoet\Cron\Workers;
4
 
5
  use Carbon\Carbon;
6
  use MailPoet\Cron\CronHelper;
 
7
  use MailPoet\Models\Newsletter;
8
  use MailPoet\Models\ScheduledTask;
9
  use MailPoet\Models\Segment;
@@ -75,9 +76,17 @@ class Scheduler {
75
  }
76
 
77
  function processPostNotificationNewsletter($newsletter, $queue) {
 
 
 
 
78
  // ensure that segments exist
79
  $segments = $newsletter->segments()->findArray();
80
  if(empty($segments)) {
 
 
 
 
81
  return $this->deleteQueueOrUpdateNextRunDate($queue, $newsletter);
82
  }
83
 
@@ -87,6 +96,10 @@ class Scheduler {
87
  $subscribers_count = $finder->addSubscribersToTaskFromSegments($queue->task(), $segments);
88
 
89
  if(empty($subscribers_count)) {
 
 
 
 
90
  return $this->deleteQueueOrUpdateNextRunDate($queue, $newsletter);
91
  }
92
 
@@ -100,6 +113,10 @@ class Scheduler {
100
  $queue->save();
101
  // update notification status
102
  $notification_history->setStatus(Newsletter::STATUS_SENDING);
 
 
 
 
103
  return true;
104
  }
105
 
4
 
5
  use Carbon\Carbon;
6
  use MailPoet\Cron\CronHelper;
7
+ use MailPoet\Logging\Logger;
8
  use MailPoet\Models\Newsletter;
9
  use MailPoet\Models\ScheduledTask;
10
  use MailPoet\Models\Segment;
76
  }
77
 
78
  function processPostNotificationNewsletter($newsletter, $queue) {
79
+ Logger::getLogger('post-notifications')->addInfo(
80
+ 'process post notification in scheduler',
81
+ ['newsletter_id' => $newsletter->id, 'task_id' => $queue->task_id]
82
+ );
83
  // ensure that segments exist
84
  $segments = $newsletter->segments()->findArray();
85
  if(empty($segments)) {
86
+ Logger::getLogger('post-notifications')->addInfo(
87
+ 'post notification no segments',
88
+ ['newsletter_id' => $newsletter->id, 'task_id' => $queue->task_id]
89
+ );
90
  return $this->deleteQueueOrUpdateNextRunDate($queue, $newsletter);
91
  }
92
 
96
  $subscribers_count = $finder->addSubscribersToTaskFromSegments($queue->task(), $segments);
97
 
98
  if(empty($subscribers_count)) {
99
+ Logger::getLogger('post-notifications')->addInfo(
100
+ 'post notification no subscribers',
101
+ ['newsletter_id' => $newsletter->id, 'task_id' => $queue->task_id]
102
+ );
103
  return $this->deleteQueueOrUpdateNextRunDate($queue, $newsletter);
104
  }
105
 
113
  $queue->save();
114
  // update notification status
115
  $notification_history->setStatus(Newsletter::STATUS_SENDING);
116
+ Logger::getLogger('post-notifications')->addInfo(
117
+ 'post notification set status to sending',
118
+ ['newsletter_id' => $newsletter->id, 'task_id' => $queue->task_id]
119
+ );
120
  return true;
121
  }
122
 
lib/Cron/Workers/SendingQueue/SendingQueue.php CHANGED
@@ -5,6 +5,7 @@ use MailPoet\Cron\CronHelper;
5
  use MailPoet\Cron\Workers\SendingQueue\Tasks\Links;
6
  use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask;
7
  use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
 
8
  use MailPoet\Mailer\MailerError;
9
  use MailPoet\Mailer\MailerLog;
10
  use MailPoet\Models\ScheduledTask as ScheduledTaskModel;
@@ -48,6 +49,10 @@ class SendingQueue {
48
  // pre-process newsletter (render, replace shortcodes/links, etc.)
49
  $newsletter = $this->newsletter_task->preProcessNewsletter($newsletter, $queue);
50
  if(!$newsletter) {
 
 
 
 
51
  $queue->delete();
52
  continue;
53
  }
5
  use MailPoet\Cron\Workers\SendingQueue\Tasks\Links;
6
  use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask;
7
  use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
8
+ use MailPoet\Logging\Logger;
9
  use MailPoet\Mailer\MailerError;
10
  use MailPoet\Mailer\MailerLog;
11
  use MailPoet\Models\ScheduledTask as ScheduledTaskModel;
49
  // pre-process newsletter (render, replace shortcodes/links, etc.)
50
  $newsletter = $this->newsletter_task->preProcessNewsletter($newsletter, $queue);
51
  if(!$newsletter) {
52
+ Logger::getLogger('newsletters')->addInfo(
53
+ 'delete task in sending queue',
54
+ ['newsletter_id' => $newsletter->id(), 'task_id' => $queue->task_id]
55
+ );
56
  $queue->delete();
57
  continue;
58
  }
lib/Models/ScheduledTask.php CHANGED
@@ -76,6 +76,18 @@ class ScheduledTask extends Model {
76
  return $this;
77
  }
78
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  static function touchAllByIds(array $ids) {
80
  ScheduledTask::rawExecute(
81
  'UPDATE `' . ScheduledTask::$_table . '`' .
76
  return $this;
77
  }
78
 
79
+ function delete() {
80
+ try {
81
+ \ORM::get_db()->beginTransaction();
82
+ ScheduledTaskSubscriber::where('task_id', $this->id)->deleteMany();
83
+ parent::delete();
84
+ \ORM::get_db()->commit();
85
+ } catch(\Exception $error) {
86
+ \ORM::get_db()->rollBack();
87
+ throw $error;
88
+ }
89
+ }
90
+
91
  static function touchAllByIds(array $ids) {
92
  ScheduledTask::rawExecute(
93
  'UPDATE `' . ScheduledTask::$_table . '`' .
lib/Newsletter/AutomatedLatestContent.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
  namespace MailPoet\Newsletter;
3
 
 
4
  use MailPoet\Newsletter\Editor\Transformer;
5
 
6
  if(!defined('ABSPATH')) exit;
@@ -29,6 +30,10 @@ class AutomatedLatestContent {
29
  }
30
 
31
  function getPosts($args, $posts_to_exclude = array()) {
 
 
 
 
32
  $posts_per_page = (!empty($args['amount']) && (int)$args['amount'] > 0)
33
  ? (int)$args['amount']
34
  : self::DEFAULT_POSTS_PER_PAGE;
@@ -70,7 +75,14 @@ class AutomatedLatestContent {
70
  }
71
 
72
  $this->_attachSentPostsFilter();
 
 
 
 
 
73
  $posts = get_posts($parameters);
 
 
74
  $this->_detachSentPostsFilter();
75
  return $posts;
76
  }
@@ -126,4 +138,18 @@ class AutomatedLatestContent {
126
  remove_action('posts_where', array($this, 'filterOutSentPosts'));
127
  }
128
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  }
1
  <?php
2
  namespace MailPoet\Newsletter;
3
 
4
+ use MailPoet\Logging\Logger;
5
  use MailPoet\Newsletter\Editor\Transformer;
6
 
7
  if(!defined('ABSPATH')) exit;
30
  }
31
 
32
  function getPosts($args, $posts_to_exclude = array()) {
33
+ Logger::getLogger('post-notifications')->addInfo(
34
+ 'loading automated latest content',
35
+ ['args' => $args, 'posts_to_exclude' => $posts_to_exclude, 'newsletter_id' => $this->newsletter_id, 'newer_than_timestamp' => $this->newer_than_timestamp]
36
+ );
37
  $posts_per_page = (!empty($args['amount']) && (int)$args['amount'] > 0)
38
  ? (int)$args['amount']
39
  : self::DEFAULT_POSTS_PER_PAGE;
75
  }
76
 
77
  $this->_attachSentPostsFilter();
78
+
79
+ Logger::getLogger('post-notifications')->addInfo(
80
+ 'getting automated latest content',
81
+ ['parameters' => $parameters]
82
+ );
83
  $posts = get_posts($parameters);
84
+ $this->logPosts($posts);
85
+
86
  $this->_detachSentPostsFilter();
87
  return $posts;
88
  }
138
  remove_action('posts_where', array($this, 'filterOutSentPosts'));
139
  }
140
  }
141
+
142
+ private function logPosts(array $posts) {
143
+ $posts_to_log = [];
144
+ foreach($posts as $post) {
145
+ $posts_to_log[] = [
146
+ 'id' => $post->ID,
147
+ 'post_date' => $post->post_date,
148
+ ];
149
+ }
150
+ Logger::getLogger('post-notifications')->addInfo(
151
+ 'automated latest content loaded posts',
152
+ ['posts' => $posts_to_log]
153
+ );
154
+ }
155
  }
lib/Newsletter/Scheduler/Scheduler.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace MailPoet\Newsletter\Scheduler;
4
 
5
  use Carbon\Carbon;
 
6
  use MailPoet\Models\Newsletter;
7
  use MailPoet\Models\NewsletterOption;
8
  use MailPoet\Models\NewsletterOptionField;
@@ -23,6 +24,10 @@ class Scheduler {
23
  const INTERVAL_NTHWEEKDAY = 'nthWeekDay';
24
 
25
  static function schedulePostNotification($post_id) {
 
 
 
 
26
  $newsletters = self::getNewsletters(Newsletter::TYPE_NOTIFICATION);
27
  if(!count($newsletters)) return false;
28
  foreach($newsletters as $newsletter) {
@@ -143,6 +148,10 @@ class Scheduler {
143
  $sending_task->status = SendingQueue::STATUS_SCHEDULED;
144
  $sending_task->scheduled_at = $next_run_date;
145
  $sending_task->save();
 
 
 
 
146
  return $sending_task;
147
  }
148
 
3
  namespace MailPoet\Newsletter\Scheduler;
4
 
5
  use Carbon\Carbon;
6
+ use MailPoet\Logging\Logger;
7
  use MailPoet\Models\Newsletter;
8
  use MailPoet\Models\NewsletterOption;
9
  use MailPoet\Models\NewsletterOptionField;
24
  const INTERVAL_NTHWEEKDAY = 'nthWeekDay';
25
 
26
  static function schedulePostNotification($post_id) {
27
+ Logger::getLogger('post-notifications')->addInfo(
28
+ 'schedule post notification hook',
29
+ ['post_id' => $post_id]
30
+ );
31
  $newsletters = self::getNewsletters(Newsletter::TYPE_NOTIFICATION);
32
  if(!count($newsletters)) return false;
33
  foreach($newsletters as $newsletter) {
148
  $sending_task->status = SendingQueue::STATUS_SCHEDULED;
149
  $sending_task->scheduled_at = $next_run_date;
150
  $sending_task->save();
151
+ Logger::getLogger('post-notifications')->addInfo(
152
+ 'schedule post notification',
153
+ ['sending_task' => $sending_task->id(), 'scheduled_at' => $next_run_date]
154
+ );
155
  return $sending_task;
156
  }
157
 
lib/Router/Endpoints/CronDaemon.php CHANGED
@@ -4,7 +4,7 @@ namespace MailPoet\Router\Endpoints;
4
 
5
  use MailPoet\Config\AccessControl;
6
  use MailPoet\Cron\CronHelper;
7
- use MailPoet\Cron\Daemon;
8
 
9
  if(!defined('ABSPATH')) exit;
10
 
@@ -28,7 +28,7 @@ class CronDaemon {
28
  }
29
 
30
  function run() {
31
- $queue = new Daemon($this->data);
32
  $queue->run();
33
  }
34
 
@@ -37,7 +37,7 @@ class CronDaemon {
37
  }
38
 
39
  function pingResponse() {
40
- $queue = new Daemon();
41
  $queue->ping();
42
  }
43
  }
4
 
5
  use MailPoet\Config\AccessControl;
6
  use MailPoet\Cron\CronHelper;
7
+ use MailPoet\Cron\DaemonHttpRunner;
8
 
9
  if(!defined('ABSPATH')) exit;
10
 
28
  }
29
 
30
  function run() {
31
+ $queue = new DaemonHttpRunner($this->data);
32
  $queue->run();
33
  }
34
 
37
  }
38
 
39
  function pingResponse() {
40
+ $queue = new DaemonHttpRunner();
41
  $queue->ping();
42
  }
43
  }
mailpoet.php CHANGED
@@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
4
 
5
  /*
6
  * Plugin Name: MailPoet 3 (New)
7
- * Version: 3.11.1
8
  * Plugin URI: http://www.mailpoet.com
9
  * Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
10
  * Author: MailPoet
@@ -18,7 +18,7 @@ if(!defined('ABSPATH')) exit;
18
  */
19
 
20
  $mailpoet_plugin = array(
21
- 'version' => '3.11.1',
22
  'filename' => __FILE__,
23
  'path' => dirname(__FILE__),
24
  'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
4
 
5
  /*
6
  * Plugin Name: MailPoet 3 (New)
7
+ * Version: 3.11.2
8
  * Plugin URI: http://www.mailpoet.com
9
  * Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
10
  * Author: MailPoet
18
  */
19
 
20
  $mailpoet_plugin = array(
21
+ 'version' => '3.11.2',
22
  'filename' => __FILE__,
23
  'path' => dirname(__FILE__),
24
  'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: mailpoet, wysija, kgjerstad
3
  Tags: newsletter, newsletter subscribers, email, welcome email, post notification, WooCommerce emails, newsletter builder, mailing list
4
  Requires at least: 4.7
5
  Tested up to: 4.9
6
- Stable tag: 3.11.1
7
  License: GPLv3
8
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
9
 
@@ -161,6 +161,14 @@ Stop by our [support site](https://www.mailpoet.com/support).
161
 
162
  == Changelog ==
163
 
 
 
 
 
 
 
 
 
164
  = 3.11.1 - 2018-10-02 =
165
  * Fixed: JS assets caching issues;
166
 
3
  Tags: newsletter, newsletter subscribers, email, welcome email, post notification, WooCommerce emails, newsletter builder, mailing list
4
  Requires at least: 4.7
5
  Tested up to: 4.9
6
+ Stable tag: 3.11.2
7
  License: GPLv3
8
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
9
 
161
 
162
  == Changelog ==
163
 
164
+ = 3.11.2 - 2018-10-09 =
165
+ * Added: Linux cron option for sending emails;
166
+ * Fixed: fatal error for admins who are not also subscribers;
167
+ * Fixed: minor style fixes;
168
+ * Fixed: added missing translation string;
169
+ * Fixed: orphaned tasks cleared after subscribers deleted;
170
+ * Fixed: minor styling issue on schedule page for Mac Chrome users.
171
+
172
  = 3.11.1 - 2018-10-02 =
173
  * Fixed: JS assets caching issues;
174
 
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit3ae7fb8a735f75fa470f55016270f278::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitbc3eb6526854d6d35f830d91b3fce48a::getLoader();
vendor/composer/ClassLoader.php CHANGED
@@ -377,7 +377,7 @@ class ClassLoader
377
  $subPath = $class;
378
  while (false !== $lastPos = strrpos($subPath, '\\')) {
379
  $subPath = substr($subPath, 0, $lastPos);
380
- $search = $subPath.'\\';
381
  if (isset($this->prefixDirsPsr4[$search])) {
382
  $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383
  foreach ($this->prefixDirsPsr4[$search] as $dir) {
377
  $subPath = $class;
378
  while (false !== $lastPos = strrpos($subPath, '\\')) {
379
  $subPath = substr($subPath, 0, $lastPos);
380
+ $search = $subPath . '\\';
381
  if (isset($this->prefixDirsPsr4[$search])) {
382
  $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383
  foreach ($this->prefixDirsPsr4[$search] as $dir) {
vendor/composer/autoload_classmap.php CHANGED
@@ -123,6 +123,7 @@ return array(
123
  'MailPoet\\Cron\\CronHelper' => $baseDir . '/lib/Cron/CronHelper.php',
124
  'MailPoet\\Cron\\CronTrigger' => $baseDir . '/lib/Cron/CronTrigger.php',
125
  'MailPoet\\Cron\\Daemon' => $baseDir . '/lib/Cron/Daemon.php',
 
126
  'MailPoet\\Cron\\Supervisor' => $baseDir . '/lib/Cron/Supervisor.php',
127
  'MailPoet\\Cron\\Triggers\\MailPoet' => $baseDir . '/lib/Cron/Triggers/MailPoet.php',
128
  'MailPoet\\Cron\\Triggers\\WordPress' => $baseDir . '/lib/Cron/Triggers/WordPress.php',
123
  'MailPoet\\Cron\\CronHelper' => $baseDir . '/lib/Cron/CronHelper.php',
124
  'MailPoet\\Cron\\CronTrigger' => $baseDir . '/lib/Cron/CronTrigger.php',
125
  'MailPoet\\Cron\\Daemon' => $baseDir . '/lib/Cron/Daemon.php',
126
+ 'MailPoet\\Cron\\DaemonHttpRunner' => $baseDir . '/lib/Cron/DaemonHttpRunner.php',
127
  'MailPoet\\Cron\\Supervisor' => $baseDir . '/lib/Cron/Supervisor.php',
128
  'MailPoet\\Cron\\Triggers\\MailPoet' => $baseDir . '/lib/Cron/Triggers/MailPoet.php',
129
  'MailPoet\\Cron\\Triggers\\WordPress' => $baseDir . '/lib/Cron/Triggers/WordPress.php',
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit3ae7fb8a735f75fa470f55016270f278
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit3ae7fb8a735f75fa470f55016270f278
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit3ae7fb8a735f75fa470f55016270f278', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit3ae7fb8a735f75fa470f55016270f278', '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\ComposerStaticInit3ae7fb8a735f75fa470f55016270f278::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit3ae7fb8a735f75fa470f55016270f278
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
- $includeFiles = Composer\Autoload\ComposerStaticInit3ae7fb8a735f75fa470f55016270f278::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
- composerRequire3ae7fb8a735f75fa470f55016270f278($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
- function composerRequire3ae7fb8a735f75fa470f55016270f278($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 ComposerAutoloaderInitbc3eb6526854d6d35f830d91b3fce48a
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitbc3eb6526854d6d35f830d91b3fce48a', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitbc3eb6526854d6d35f830d91b3fce48a', '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\ComposerStaticInitbc3eb6526854d6d35f830d91b3fce48a::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\ComposerStaticInitbc3eb6526854d6d35f830d91b3fce48a::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequirebc3eb6526854d6d35f830d91b3fce48a($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
+ function composerRequirebc3eb6526854d6d35f830d91b3fce48a($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 ComposerStaticInit3ae7fb8a735f75fa470f55016270f278
8
  {
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@@ -250,6 +250,7 @@ class ComposerStaticInit3ae7fb8a735f75fa470f55016270f278
250
  'MailPoet\\Cron\\CronHelper' => __DIR__ . '/../..' . '/lib/Cron/CronHelper.php',
251
  'MailPoet\\Cron\\CronTrigger' => __DIR__ . '/../..' . '/lib/Cron/CronTrigger.php',
252
  'MailPoet\\Cron\\Daemon' => __DIR__ . '/../..' . '/lib/Cron/Daemon.php',
 
253
  'MailPoet\\Cron\\Supervisor' => __DIR__ . '/../..' . '/lib/Cron/Supervisor.php',
254
  'MailPoet\\Cron\\Triggers\\MailPoet' => __DIR__ . '/../..' . '/lib/Cron/Triggers/MailPoet.php',
255
  'MailPoet\\Cron\\Triggers\\WordPress' => __DIR__ . '/../..' . '/lib/Cron/Triggers/WordPress.php',
@@ -1224,11 +1225,11 @@ class ComposerStaticInit3ae7fb8a735f75fa470f55016270f278
1224
  public static function getInitializer(ClassLoader $loader)
1225
  {
1226
  return \Closure::bind(function () use ($loader) {
1227
- $loader->prefixLengthsPsr4 = ComposerStaticInit3ae7fb8a735f75fa470f55016270f278::$prefixLengthsPsr4;
1228
- $loader->prefixDirsPsr4 = ComposerStaticInit3ae7fb8a735f75fa470f55016270f278::$prefixDirsPsr4;
1229
- $loader->fallbackDirsPsr4 = ComposerStaticInit3ae7fb8a735f75fa470f55016270f278::$fallbackDirsPsr4;
1230
- $loader->prefixesPsr0 = ComposerStaticInit3ae7fb8a735f75fa470f55016270f278::$prefixesPsr0;
1231
- $loader->classMap = ComposerStaticInit3ae7fb8a735f75fa470f55016270f278::$classMap;
1232
 
1233
  }, null, ClassLoader::class);
1234
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInitbc3eb6526854d6d35f830d91b3fce48a
8
  {
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
250
  'MailPoet\\Cron\\CronHelper' => __DIR__ . '/../..' . '/lib/Cron/CronHelper.php',
251
  'MailPoet\\Cron\\CronTrigger' => __DIR__ . '/../..' . '/lib/Cron/CronTrigger.php',
252
  'MailPoet\\Cron\\Daemon' => __DIR__ . '/../..' . '/lib/Cron/Daemon.php',
253
+ 'MailPoet\\Cron\\DaemonHttpRunner' => __DIR__ . '/../..' . '/lib/Cron/DaemonHttpRunner.php',
254
  'MailPoet\\Cron\\Supervisor' => __DIR__ . '/../..' . '/lib/Cron/Supervisor.php',
255
  'MailPoet\\Cron\\Triggers\\MailPoet' => __DIR__ . '/../..' . '/lib/Cron/Triggers/MailPoet.php',
256
  'MailPoet\\Cron\\Triggers\\WordPress' => __DIR__ . '/../..' . '/lib/Cron/Triggers/WordPress.php',
1225
  public static function getInitializer(ClassLoader $loader)
1226
  {
1227
  return \Closure::bind(function () use ($loader) {
1228
+ $loader->prefixLengthsPsr4 = ComposerStaticInitbc3eb6526854d6d35f830d91b3fce48a::$prefixLengthsPsr4;
1229
+ $loader->prefixDirsPsr4 = ComposerStaticInitbc3eb6526854d6d35f830d91b3fce48a::$prefixDirsPsr4;
1230
+ $loader->fallbackDirsPsr4 = ComposerStaticInitbc3eb6526854d6d35f830d91b3fce48a::$fallbackDirsPsr4;
1231
+ $loader->prefixesPsr0 = ComposerStaticInitbc3eb6526854d6d35f830d91b3fce48a::$prefixesPsr0;
1232
+ $loader->classMap = ComposerStaticInitbc3eb6526854d6d35f830d91b3fce48a::$classMap;
1233
 
1234
  }, null, ClassLoader::class);
1235
  }
views/settings.html CHANGED
@@ -166,6 +166,16 @@
166
  toggleReCaptchaSettings();
167
  $('#settings_re_captcha_tokens_error').hide();
168
 
 
 
 
 
 
 
 
 
 
 
169
  // page preview
170
  $('.mailpoet_page_preview').on('click', function() {
171
  var selection = $(this).siblings('.mailpoet_page_selection');
166
  toggleReCaptchaSettings();
167
  $('#settings_re_captcha_tokens_error').hide();
168
 
169
+ function toggleLinuxCronSettings() {
170
+ if ($('input[name="cron_trigger[method]"]:checked').val() === '<%= cron_trigger.linux_cron %>') {
171
+ $('#settings_linux_cron').show();
172
+ } else {
173
+ $('#settings_linux_cron').hide();
174
+ }
175
+ }
176
+ $('input[name="cron_trigger[method]"]').on('click', toggleLinuxCronSettings);
177
+ toggleLinuxCronSettings();
178
+
179
  // page preview
180
  $('.mailpoet_page_preview').on('click', function() {
181
  var selection = $(this).siblings('.mailpoet_page_selection');
views/settings/advanced.html CHANGED
@@ -65,6 +65,35 @@
65
  %>
66
  </label>
67
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  </td>
69
  </tr>
70
  <!-- roles and capabilities -->
65
  %>
66
  </label>
67
  </p>
68
+ <p>
69
+ <label>
70
+ <input
71
+ type="radio"
72
+ name="cron_trigger[method]"
73
+ value="<%= cron_trigger.linux_cron %>"
74
+ <% if (settings.cron_trigger.method == cron_trigger.linux_cron) %>
75
+ checked="checked"
76
+ <% endif %>
77
+ /><%= __("Server side cron (Linux cron)")
78
+ %>
79
+ </label>
80
+ </p>
81
+ <div id="settings_linux_cron">
82
+ <p>
83
+ <%= __("To use this option please add this command to your crontab:") %><br>
84
+ <input
85
+ value="php <%= linux_cron_path %>/mailpoet-cron.php <%= ABSPATH %>"
86
+ class="large-text"
87
+ readonly
88
+ />
89
+ <p>
90
+ <%= __("With the frequency of running it every minute:") %><br>
91
+ <input
92
+ value="*/1 * * * *"
93
+ class="large-text"
94
+ readonly
95
+ />
96
+ </div>
97
  </td>
98
  </tr>
99
  <!-- roles and capabilities -->
views/settings/mta.html CHANGED
@@ -99,7 +99,7 @@
99
  <div class="mailpoet_actions">
100
  <div class="mailpoet_invalid_key <% if(mss_key_valid) %> mailpoet_hidden <% endif %>">
101
  <a class="button-primary" href="https://www.mailpoet.com/free-plan/" rel="noopener noreferrer" target="_blank"><%= __('Get a free key') %></a>
102
- or
103
  <%=
104
  __("[link]enter your key[/link]")
105
  |replaceLinkTags('#premium')
99
  <div class="mailpoet_actions">
100
  <div class="mailpoet_invalid_key <% if(mss_key_valid) %> mailpoet_hidden <% endif %>">
101
  <a class="button-primary" href="https://www.mailpoet.com/free-plan/" rel="noopener noreferrer" target="_blank"><%= __('Get a free key') %></a>
102
+ <%= __("or") %>
103
  <%=
104
  __("[link]enter your key[/link]")
105
  |replaceLinkTags('#premium')