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 | |
| Version | 3.11.2 |
| Comparing to | |
| See all releases | |
Code changes from version 3.11.1 to 3.11.2
- assets/css/{admin.86751c85.css → admin.90fe3283.css} +6 -3
- assets/css/manifest.json +1 -1
- assets/js/{admin.41cfe984.js → admin.eaab3da3.js} +1 -1
- assets/js/{admin_vendor.41cfe984.js → admin_vendor.eaab3da3.js} +1 -2
- assets/js/{form_editor.41cfe984.js → form_editor.eaab3da3.js} +0 -0
- assets/js/{mailpoet.41cfe984.js → mailpoet.eaab3da3.js} +0 -0
- assets/js/manifest.json +6 -6
- assets/js/{newsletter_editor.41cfe984.js → newsletter_editor.eaab3da3.js} +0 -0
- assets/js/{vendor.41cfe984.js → vendor.eaab3da3.js} +0 -0
- lang/mailpoet-ca.mo +0 -0
- lang/mailpoet-da_DK.mo +0 -0
- lang/mailpoet-de_DE.mo +0 -0
- lang/mailpoet-es_ES.mo +0 -0
- lang/mailpoet-fa_IR.mo +0 -0
- lang/mailpoet-fr_CA.mo +0 -0
- lang/mailpoet-fr_FR.mo +0 -0
- lang/mailpoet-it_IT.mo +0 -0
- lang/mailpoet-ja.mo +0 -0
- lang/mailpoet-nl_NL.mo +0 -0
- lang/mailpoet-pl_PL.mo +0 -0
- lang/mailpoet-pt_BR.mo +0 -0
- lang/mailpoet-pt_PT.mo +0 -0
- lang/mailpoet-ru_RU.mo +0 -0
- lang/mailpoet-sq.mo +0 -0
- lang/mailpoet-sv_SE.mo +0 -0
- lang/mailpoet-tr_TR.mo +0 -0
- lang/mailpoet-zh_CN.mo +0 -0
- lang/mailpoet.pot +63 -47
- lib/Config/Menu.php +5 -1
- lib/Cron/CronHelper.php +3 -3
- lib/Cron/CronTrigger.php +2 -1
- lib/Cron/Daemon.php +4 -89
- lib/Cron/DaemonHttpRunner.php +112 -0
- lib/Cron/Supervisor.php +1 -1
- lib/Cron/Triggers/MailPoet.php +1 -1
- lib/Cron/Workers/Scheduler.php +17 -0
- lib/Cron/Workers/SendingQueue/SendingQueue.php +5 -0
- lib/Models/ScheduledTask.php +12 -0
- lib/Newsletter/AutomatedLatestContent.php +26 -0
- lib/Newsletter/Scheduler/Scheduler.php +9 -0
- lib/Router/Endpoints/CronDaemon.php +3 -3
- mailpoet.php +2 -2
- readme.txt +9 -1
- vendor/autoload.php +1 -1
- vendor/composer/ClassLoader.php +1 -1
- vendor/composer/autoload_classmap.php +1 -0
- vendor/composer/autoload_real.php +7 -7
- vendor/composer/autoload_static.php +7 -6
- views/settings.html +10 -0
- views/settings/advanced.html +29 -0
- 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.
|
| 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: '
|
| 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 |
-
|
| 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.
|
| 5 |
-
"admin_vendor.js": "admin_vendor.
|
| 6 |
-
"form_editor.js": "form_editor.
|
| 7 |
-
"mailpoet.js": "mailpoet.
|
| 8 |
-
"newsletter_editor.js": "newsletter_editor.
|
| 9 |
-
"vendor.js": "vendor.
|
| 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-
|
| 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:
|
| 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:
|
| 482 |
msgid "In any WordPress role"
|
| 483 |
msgstr ""
|
| 484 |
|
| 485 |
-
#: lib/Config/Menu.php:
|
| 486 |
msgid "WooCommerce"
|
| 487 |
msgstr ""
|
| 488 |
|
| 489 |
-
#: lib/Config/Menu.php:
|
| 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:
|
| 496 |
msgid "Abandoned Shopping Cart"
|
| 497 |
msgstr ""
|
| 498 |
|
| 499 |
-
#: lib/Config/Menu.php:
|
| 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:
|
| 507 |
msgid "Must-have"
|
| 508 |
msgstr ""
|
| 509 |
|
| 510 |
-
#: lib/Config/Menu.php:
|
| 511 |
msgid "Big Spender"
|
| 512 |
msgstr ""
|
| 513 |
|
| 514 |
-
#: lib/Config/Menu.php:
|
| 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:
|
| 521 |
msgid "Smart to have"
|
| 522 |
msgstr ""
|
| 523 |
|
| 524 |
-
#: lib/Config/Menu.php:
|
| 525 |
msgid "First Purchase"
|
| 526 |
msgstr ""
|
| 527 |
|
| 528 |
-
#: lib/Config/Menu.php:
|
| 529 |
msgid "Let MailPoet send an email to customers who make their first purchase."
|
| 530 |
msgstr ""
|
| 531 |
|
| 532 |
-
#: lib/Config/Menu.php:
|
| 533 |
msgid "Purchased In This Category"
|
| 534 |
msgstr ""
|
| 535 |
|
| 536 |
-
#: lib/Config/Menu.php:
|
| 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:
|
| 543 |
msgid "Purchased This Product"
|
| 544 |
msgstr ""
|
| 545 |
|
| 546 |
-
#: lib/Config/Menu.php:
|
| 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/
|
| 1187 |
msgid "Invalid or missing request data."
|
| 1188 |
msgstr ""
|
| 1189 |
|
| 1190 |
-
#: lib/Cron/
|
| 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:
|
| 1836 |
-
#: views/settings/advanced.html:
|
| 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:
|
| 2216 |
-
#: views/settings/advanced.html:
|
| 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:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4683 |
msgid "Roles and capabilities"
|
| 4684 |
msgstr ""
|
| 4685 |
|
| 4686 |
-
#: views/settings/advanced.html:
|
| 4687 |
msgid "Manage which WordPress roles access which features of MailPoet."
|
| 4688 |
msgstr ""
|
| 4689 |
|
| 4690 |
-
#: views/settings/advanced.html:
|
| 4691 |
msgid "Manage using the Members plugin"
|
| 4692 |
msgstr ""
|
| 4693 |
|
| 4694 |
-
#: views/settings/advanced.html:
|
| 4695 |
msgid "Install the plugin [link]Members[/link] (free) to manage permissions."
|
| 4696 |
msgstr ""
|
| 4697 |
|
| 4698 |
-
#: views/settings/advanced.html:
|
| 4699 |
msgid "Open and click tracking"
|
| 4700 |
msgstr ""
|
| 4701 |
|
| 4702 |
-
#: views/settings/advanced.html:
|
| 4703 |
msgid "Enable or disable open and click tracking."
|
| 4704 |
msgstr ""
|
| 4705 |
|
| 4706 |
-
#: views/settings/advanced.html:
|
| 4707 |
msgid "Share anonymous data"
|
| 4708 |
msgstr ""
|
| 4709 |
|
| 4710 |
-
#: views/settings/advanced.html:
|
| 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:
|
| 4717 |
msgid "Enable reCAPTCHA"
|
| 4718 |
msgstr ""
|
| 4719 |
|
| 4720 |
-
#: views/settings/advanced.html:
|
| 4721 |
msgid "Use reCAPTCHA to protect MailPoet subscription forms."
|
| 4722 |
msgstr ""
|
| 4723 |
|
| 4724 |
-
#: views/settings/advanced.html:
|
| 4725 |
msgid "Sign up for an API key pair here."
|
| 4726 |
msgstr ""
|
| 4727 |
|
| 4728 |
-
#: views/settings/advanced.html:
|
| 4729 |
msgid "Your reCAPTCHA Site Key"
|
| 4730 |
msgstr ""
|
| 4731 |
|
| 4732 |
-
#: views/settings/advanced.html:
|
| 4733 |
msgid "Your reCAPTCHA Secret Key"
|
| 4734 |
msgstr ""
|
| 4735 |
|
| 4736 |
-
#: views/settings/advanced.html:
|
| 4737 |
msgid "Please fill the reCAPTCHA keys."
|
| 4738 |
msgstr ""
|
| 4739 |
|
| 4740 |
-
#: views/settings/advanced.html:
|
| 4741 |
msgid "Reinstall from scratch"
|
| 4742 |
msgstr ""
|
| 4743 |
|
| 4744 |
-
#: views/settings/advanced.html:
|
| 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:
|
| 4751 |
msgid "Reinstall now..."
|
| 4752 |
msgstr ""
|
| 4753 |
|
| 4754 |
-
#: views/settings/advanced.html:
|
| 4755 |
msgid "Logging"
|
| 4756 |
msgstr ""
|
| 4757 |
|
| 4758 |
-
#: views/settings/advanced.html:
|
| 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:
|
| 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:
|
| 6043 |
msgctxt "support article link label"
|
| 6044 |
msgid "Read more."
|
| 6045 |
msgstr ""
|
| 6046 |
|
| 6047 |
-
#: views/settings/advanced.html:
|
| 6048 |
msgctxt "In settings: \"Logging: Everything\""
|
| 6049 |
msgid "Everything"
|
| 6050 |
msgstr ""
|
| 6051 |
|
| 6052 |
-
#: views/settings/advanced.html:
|
| 6053 |
msgctxt "In settings: \"Logging: Errors only\""
|
| 6054 |
msgid "Errors only"
|
| 6055 |
msgstr ""
|
| 6056 |
|
| 6057 |
-
#: views/settings/advanced.html:
|
| 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(
|
| 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(
|
| 87 |
-
|
| 88 |
$response;
|
| 89 |
return (!$validate_response) ?
|
| 90 |
$response :
|
| 91 |
-
$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 |
-
|
| 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
|
| 29 |
-
$
|
| 30 |
-
$
|
| 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\
|
| 8 |
|
| 9 |
if(!defined('ABSPATH')) exit;
|
| 10 |
|
|
@@ -28,7 +28,7 @@ class CronDaemon {
|
|
| 28 |
}
|
| 29 |
|
| 30 |
function run() {
|
| 31 |
-
$queue = new
|
| 32 |
$queue->run();
|
| 33 |
}
|
| 34 |
|
|
@@ -37,7 +37,7 @@ class CronDaemon {
|
|
| 37 |
}
|
| 38 |
|
| 39 |
function pingResponse() {
|
| 40 |
-
$queue = new
|
| 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.
|
| 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.
|
| 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.
|
| 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
|
| 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
|
| 6 |
{
|
| 7 |
private static $loader;
|
| 8 |
|
|
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit3ae7fb8a735f75fa470f55016270f278
|
|
| 19 |
return self::$loader;
|
| 20 |
}
|
| 21 |
|
| 22 |
-
spl_autoload_register(array('
|
| 23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
| 24 |
-
spl_autoload_unregister(array('
|
| 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\
|
| 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\
|
| 52 |
} else {
|
| 53 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
| 54 |
}
|
| 55 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
| 56 |
-
|
| 57 |
}
|
| 58 |
|
| 59 |
return $loader;
|
| 60 |
}
|
| 61 |
}
|
| 62 |
|
| 63 |
-
function
|
| 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
|
| 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 =
|
| 1228 |
-
$loader->prefixDirsPsr4 =
|
| 1229 |
-
$loader->fallbackDirsPsr4 =
|
| 1230 |
-
$loader->prefixesPsr0 =
|
| 1231 |
-
$loader->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')
|
